Unix 脚本在读取文件第一行后终止

Unix 脚本在读取文件第一行后终止

我正在尝试计算文件中每行的选项卡数量,并在条件匹配时将该行打印到另一个文件。但脚本只读取第一行并终止。

请让我知道下面有什么问题,

#!/bin/bash
set -e
set -o pipefail

filename="0101.tsv"
while IFS= read -r line;do

s=$(awk '{print gsub(/\t/,"")}')
echo $s

if [[ $s -eq 995 ]]; then
printf "%s\n" "$line"
continue
fi

done < $filename > abc.tsv

谢谢!。

答案1

您似乎想要计算文件中制表符分隔字段的数量。为此,您必须在选项卡上拆分输入行并对它们进行计数。 awk可以自动执行此操作,并且它还有一个用于表示结果字段数的特殊变量NF

如果你想打印所有包含 996 个字段(995 个标签)的行:

awk -F '\t' 'NF == 996' <file

这是一种简写方式

awk 'BEGIN { FS = "\t" } NF == 996 { print }' <file

其中print表示print $0,即打印输入记录(行),FS是输入字段分隔符。

每当您发现自己从文件中提取文本行并将它们传递给awksed循环中的类似工具时,总是有一种更有效的方法来执行相同的操作。请注意,上述命令仅调用awk一次,而您的解决方案(如果将数据正确传递给awk)将调用awk文件中的每一行。

答案2

@steeldriver 的onelinersawk可以完成这项工作,但是如果你想要一个 bash shellscript 读取行,你可以这样做,

#!/bin/bash

set -e
set -o pipefail

filename="0101.tsv"
while IFS= read -r line
do
 s=0
 len=${#line}
# echo "line=$line"
# echo "len=$len"
 for (( i=0; i<$len; i++ ))
 do
  if [ "${line:i:1}" ==  $'\t' ]
  then
   s=$((s +1))
  fi
 done
 echo $s

 if [[ "$s" == "995" ]]; then
  printf "%s\n" "$line"
  continue
 fi
done < "$filename" > abc.tsv

相关内容