满足某些条件时,如何将字符串附加到一行?

Posted

技术标签:

【中文标题】满足某些条件时,如何将字符串附加到一行?【英文标题】:How can I append a string to a line when certain conditions are met? 【发布时间】:2017-06-09 03:23:53 【问题描述】:

我正在处理大型 .txt 文件,我们正在尝试确定哪些不符合一行中正确数量的字符(最多 80 个字符)。

为了这个例子,假设我们每行需要 10 个字符,我需要为没有的每一行附加“(+额外字符数)”和“(-缺失字符数)”正好 10 个字符。

这是我目前所拥有的:

while IFS='' read -r line || [[ -n "$line" ]]; do
  if [[ "$#line" -gt 10 ]]; then
    echo "Mo dan 10 D: $#line"
  elif [[ "$#line" -lt 10 ]]; then
    echo "Less dan 10 D: $#line"
  fi

done < "$1"

我一直在寻找一种方法来附加我在相应行中回显的这两个字符串,以便我们识别它们。

我研究了 awk 和 sed,但无法正确循环遍历整个 .txt 文件、计算每行中的字符数并附加一个带有适当消息的字符串。

希望在 shell 脚本或 awk 或 sed 解决方案方面提供一些帮助。 谢谢。

编辑:这是一个示例输入文件(注意空格也算作字符)

Line 1****
Line 2*****
Line 3*
Line 4****
Line 5****
Line 6**
Line 7****
Line 8********
Line 9****

这是想要的输出

Line 1****
Line 2*****(+1)
Line 3*(-3)
Line 4****
Line 5****
Line 6**(-2)
Line 7****
Line 8********(+4)
Line 9****

【问题讨论】:

如果您解析大文件,我会再次建议任何“if”循环或逐行阅读。不能用 awk 或 sed 编译你的答案(也不要使用 sed)。只要简单的正则表达式无法解决问题,我个人更喜欢使用 Python。 【参考方案1】:

出于性能原因,使用 shell 循环 处理文件的行是错误的方法(除非文件非常小)。

awk 这样的文本处理实用程序是更好的选择

awk -v targetLen=10 '
  diff = length($0) - targetLen  # input line ($0) does not have the expected length
    $0 = $0 "(" (diff > 0 ? "+" : "") diff ")" # append diff (with +, if positive)
  
  1  # Print the (possibly modified) line.
' <<'EOF'  # sample input as a here-document
1234567890
123456789
123456789012
EOF

这会产生:

1234567890
123456789(-1)
123456789012(+2)

警告:BSD/macOS awk 实现不支持区域设置,因此它的 length 函数计数 字节,它仅适用于 ASCII 范围字符。

【讨论】:

【参考方案2】:
$ cat lines.in
Line 1****
Line 2*****
Line 3*
Line 4****
Line 5****
Line 6**
Line 7****
Line 8********
Line 9****

$ cat lines.sh
#!/bin/bash
mark=10
while IFS='' read -r line || [[ -n "$line" ]]; do
    diff=$(( $#line - mark ))
    if [ $diff -eq 0 ]; then
        echo "$line"
    else
        printf "%s (%+d)\n" "$line" "$diff"
    fi
done < "$1"

$ ./lines.sh lines.in
Line 1****
Line 2***** (+1)
Line 3* (-3)
Line 4****
Line 5****
Line 6** (-2)
Line 7****
Line 8******** (+4)
Line 9****

【讨论】:

【参考方案3】:

我的答案基于你的原始脚本

#!/bin/bash

while IFS='' read -r line || [[ -n "$line" ]]; do
  nchars=$#line
  target=10
  if [[ $nchars -gt $target ]]; then
          echo "$line+($((nchars-target)))"
  elif [[ $nchars -lt $target ]]; then
          echo "$line-($((target-nchars)))"
  else
      echo "$line"
  fi

done < "$1"

像这样使用bash evalscript inputfile &gt; outputfile

【讨论】:

以上是关于满足某些条件时,如何将字符串附加到一行?的主要内容,如果未能解决你的问题,请参考以下文章

满足条件时捕获图像

如何检查xml值的条件?

如何将图像垂直对齐到某些文本第一行的中心?

如果在 R 中满足条件,则从前一行获取值并连接

仅在满足条件时如何启动调试器

如何显示多个满足特定条件的单元格的内容?