AWK脚本以及循环和if条件

时间:2015-04-10 00:54:00

标签: shell awk grep

输入文件如下

827 819
830 826
828 752
756 694
828 728
821 701
724 708
826 842
719 713
764 783
752 828
694 756

#$1是我的第一行,$ 2是我的第二行。我试图省略第11行的行,这些行与第3行相同但具有交换值。基本上,每1美元2美元也有2美元1美元,我想省略后者。这只是数据的一小部分。实际数据集中有许多这样的值。

我试过以下内容:

awk -F “ “ ‘{ for i in cat 686.edges.txt | if [ expr $1 $2 == expr $2 $1 ] then #Evaluating the condition from file

awk -F “ “ ‘{ print $2  $1 }’ >> t.txt else ‘{ print “ Not found “ } fi #Printing all the $y $x into a file

awk -F “ “ ‘{ for i in cat t.txt} | grep -v "$1 $2" 686.edges.txt >> new.txt

我正在读取来自t.txt的输入,这是上一个操作的结果,并从主文件中删除所有输入并将其写入new.txt

我无法执行,因为我遇到了错误。任何人都可以评估上述内容并纠正我。

1 个答案:

答案 0 :(得分:2)

这将打印所有行,除非先前已经看到该行的反面:

$ awk '!seen[$2" "$1] {print} {seen[$0]=1}' t.txt
827 819
830 826
828 752
756 694
828 728
821 701
724 708
826 842
719 713
764 783

这假定列由空格分隔。如果它们被例如制表符分隔,则需要对代码进行微小的更改。

要将输出写入new.txt而不是终端,请使用:

awk '!seen[$2" "$1] {print} {seen[$0]=1}' t.txt >new.txt

如何运作

awk一次读取一条记录(行)。每行分为字段(列)。我们使用数组seen来跟踪先前看到的(反向)行。

  • !seen[$2" "$1] {print}

    如果以前没有看到当前行的反转,则打印该行。 (!是"不是"的awk符号。)

  • {seen[$0]=1}

    将当前行标记为已显示。

替代:省略先前看到的行,无论顺序如何

这将省略打印之前以原样或相反顺序显示的任何行:

awk '0==seen[$0] {print} {seen[$0]=1; seen[$2" "$1]=1}' t.txt >new.txt

使用多维数组的解决方案

正如Glenn Jackman所说,如果你的awk支持多维数组,那么可以写上面两个解决方案:

awk --posix '!seen[$2,$1] {print} {seen[$1,$2]=1;}' t.txt >new.txt 

awk '!seen[$1,$2] {print} {seen[$1,$2]=1; seen[$2,$1]=1}' t.txt >new.txt

shellter指出原始 AWK编程语言(第52-3页)支持这种表示法。另一方面,Grymoire将此表示法描述为"无效"。因此,它可能不适用于所有版本的awk。但是,它受GNU awk(Linux)的支持。因为POSIX需要这种表示法,所以它可能适用于所有现代 awks。