类似于问题“仅当其中的每一列都是 $VAR1 或 $VAR2 时才删除整行”
但它是删除整个列,并且基于列中每个行的组成
我有一个文本文件,其中列号和行号始终会变化,并且仅当所述列中的每一行等于 $VAR1 或 $VAR2 时才从 txt 文件中删除所有列。例如:
假设 $VAR1="X" 和 $VAR2="N" ,我想删除 $VAR1 和 $VAR2 组成整个列的任何列。
这将是我的输入:
hajn 32 ahnnd namm X 543 asfn F
namd 90 jsnfu namm X 098 asfn S
5739 dw 32eff Sfff N asd 3123 1
这将是我想要的输出:
hajn 32 ahnnd namm 543 asfn F
namd 90 jsnfu namm 098 asfn S
5739 dw 32eff Sfff asd 3123 1
我可以用循环解决这个问题,但我想知道是否有一种强大的单行方法可以做到这一点,最好是 awk。
答案1
看一下这个。
$ cat data
hajn 32 ahnnd namm X 543 asfn F
namd 90 jsnfu namm X 098 asfn S
5739 dw 32eff Sfff N asd 3123 1
使用带有 if 表达式和 or 表达式的 awk ||
,如果是,则排除 cloumn #5 并打印其余数据。
$ awk '{ if ($5=="X" || $5=="N") { $5=""; print } }' < data
hajn 32 ahnnd namm 543 asfn F
namd 90 jsnfu namm 098 asfn S
5739 dw 32eff Sfff asd 3123 1
答案2
尝试了下面的方法,效果也很好
VAR1="X"
VAR2="N"
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 VAR1="$VAR1" -v VAR2="$VAR2" '$i == VAR1||$i == VAR2{$i="";print $0}' filename; done
输出
hajn 32 ahnnd namm 543 asfn F
namd 90 jsnfu namm 098 asfn S
5739 dw 32eff Sfff asd 3123 1
答案3
您将需要存储这些行,因为在检查完最后一行之前无法做出删除任何列的决定。
$ perl -lane '
push @{$A[$.]}, @F;my $i;
$h[$i++] ||= !/X/ && !/N/ for @F}{
my @I2P = grep { $h[$_] } 0 .. $#h;
print join $", @{$A[$_]}[@I2P] for 1 .. $#A;
' inp