我有一个制表符列表文件。我想检查每行是否有相同数量的选项卡。
第一步,我想打印每行的选项卡数。
我已经尝试过grep -o '\t' infile | wc -l
,但我的实现是grep
这样的grep: invalid option -- o
。还有其他办法吗?
很高兴拥有:如果可能的话,由于个人喜好,我更喜欢使用 util(grep、cat 等)工具来完成此操作,最好是不是 awk
或 bash 脚本。
答案1
我认为sed
等不适合这个,一个简单的方法是使用awk
制表符作为字段分隔符进行调用:
printf $'hello\tworld\thugo\nfoo\tbar\nbaz\n' | awk -F$'\t' '{print NF-1;}'
这使
2
1
0
答案2
如果您的目标只是检测每行是否始终有相同数量的选项卡(没有 bash,没有 awk):
sed 's/[^\t]//g' file | sort -u | wc -l
如果输出 1,那就很好了!
或者,替换sed
为tr
:
tr -cd \\t\\n < file | sort -u | wc -l
或者如果您喜欢猫的无用用途并且不喜欢连接选项:
cat file | tr -c -d \\t\\n | sort -u | wc -l
诀窍是删除每行上的所有非制表符,然后对剩下的内容进行排序/统一。
答案3
老实说,最简单的方法是使用awk
:
awk -F'\t' '{print NF-1}' foo
NF
是字段的数量,-F'\t'
告诉awk
在选项卡上拆分字段,这样选项卡的数量将比字段的数量少一,这就是我们有awk
print 的原因NF-1
。
如果你真的不想使用awk
你可以这样做(笔记:这不计算每行末尾的尾随制表符):
$ while read line; do echo "$line" | fold -1 | grep -c $'\t'; done < foo
2
4
0
1
0
要处理前导和尾随制表符以及其他奇怪的字符(例如反斜杠),请改为执行以下操作:
$ while IFS= read line; do echo "$line" | fold -1 | grep -c $'\t'; done < foo
while read lines; do ... ; done < foo
:将文件的每一行读foo
入变量$line
。echo "$line" | fold -1
:折叠命令将每行打印一个字符grep -c $'\t'
:这在文件 ($line
) 的每一行上运行,但由于$line
已折叠为每行一个字符,因此grep -c
将计算该行中的制表符数量。如果您不fold
首先计算,grep -c
将计算匹配行的数量,并且不会为您提供制表符计数每线。
当然,您也可以使用 Perl,但我想这也不可用。无论如何,这是一种方法:
perl -lne '@a=/\t/g;print scalar @a' foo
答案4
我意识到为时已晚,但OP的命令行几乎是正确的。他只需要 TAB 前面的 $ ('\t')
grep -o $'\t' infile | wc -l
正是他所追求的。