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

时间:2017-06-09 03:23:53

标签: bash shell awk sed

我正在处理大型.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****

3 个答案:

答案 0 :(得分:3)

出于性能原因,使用 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范围字符工作

答案 1 :(得分:0)

$ 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****

答案 2 :(得分:0)

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

#!/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 > outputfile

一样使用它