Gil*_*les 5 awk text-processing
我需要一个命令来删除文本文件中的任何列,如果它们在列(具有不同行数的列)中有 =>${MaxAllowedNumberOfFs} 'F's 。
我有一些接近的伪代码,但我不知道如何设置匹配数限制器。
假设限制器设置为 3,示例输入文件是:
F G F H H
G F F F A
F G F F F
F F F T F
Run Code Online (Sandbox Code Playgroud)
那么所需的输出将是:
G H H
F F A
G F F
F T F
Run Code Online (Sandbox Code Playgroud)
接近的伪代码(限制器可以并且会根据文件而改变):
MaxAllowedNumberOfFs="1012"
Count_of_columns=`awk '{print NF}' filename | sort -nr | sed -n '$p'`
for((i=1;i<=$Count_of_columns;i++)); do awk -v i="$i" -v x="$MaxAllowedNumberOfFs" '$i == F =>x number of times {$i="";print $0}' filename; done
Run Code Online (Sandbox Code Playgroud)
显然,我可以使用 grep 遍历所有列,计算列中出现的次数,然后删除不符合条件的列。但这真的很慢。真的想要一个漂亮的 awk 命令,但我没有 awk 技能
一种方法是读取文件两次。第一次计算 F,第二次输出该行。所以像
#!/bin/sh
awk -v n=3 '
NR==FNR { for (i=1;i<=NF;i++) { if ($i == "F") { c[i]++ }} ;next }
{ for (i=1;i<=NF;i++) { if (c[i] < n) { printf("%s ", $i) } } ;printf("\n") }
' filename filename
Run Code Online (Sandbox Code Playgroud)
这NR==FNR
是一个技巧来判断这是我们第一次还是第二次读取文件。假设文件中有任何行,那么仅在第一次读取文件时才为真。该数组c
是该列中 F 字符数的计数。表示next
该行的所有处理在第一次读取文件时已完成。第二行在第二次读取文件时执行。