假设我有一个包含此格式内容的文件:
6 8
6 9
12 20
6
8
9
12
20
35
如果在下一行中找到了数字(从第1列或第2列),我想删除所有行,无论它是在第一列还是第二列,包括找到初始数字的行。
所以我应该这样做:
35
我尝试过使用
awk '{for(i=1;i<=NF;i++){if($i in a){next};a[$i]}} 1'
有一种简单的方法吗?
答案 0 :(得分:3)
这一行应该有所帮助:
awk 'NR==FNR{a[$0]++;next}{for(i=1;i<=NF;i++)if(a[$i]>1)next}7'
RS=" |\n" file RS="\n" file
使用此输入文件:
100 200 300
6 8
6 9
12 20
6
8
9
12
20
35
上面的单行将输出:
100 200 300
35
答案 1 :(得分:3)
您想要查找仅出现一次的数字。让我添加&#34; 42&#34;与&#34; 35&#34;
在同一行的文件$ cat file
6 8
6 9
12 20
6
8
9
12
20
35 42
查找仅出现一次的所有数字:
$ tr -s "[:blank:]" "\n" < file | sort -n | uniq -u
35
42
但是,它并没有在文件中显示行,所以
$ grep -n -Fw -f <(tr -s "[:blank:]" "\n" < file | sort -n | uniq -u) file
9:35 42
我添加了-n
选项仅用于效果,以显示我们从文件中获得第9行。
答案 2 :(得分:2)
您最初编写的代码在以下条件下完美运行:打印当前行,当且仅当任何之前的行没有在当前行中列出的数字时。但是,您不要求上一个,而是下一个。
简单的解决方案是输入tac
并返回tac
。
$ tac <file> | awk '{for(i=1;i<=NF;i++){if($i in a) next;a[$i]}}1' | tac
如果您想使用单个awk
,那么您必须先存储这些行并在之后处理它们,因为它还有点麻烦:
这为您提供以下内容:
双通:
$ awk '(NR==FNR){ for(i=1;i<=NF;i++) a[$i]++; next }'
{ b=0; for(i=1;i<=NF;i++) b+=--a[$i] }
!b; <file> <file>
<强>存储器强>
$ awk '{ m[NR]=$0; for(i=1;i<=NF;i++) a[$i]++; next }
END { for (n=1;n<=NR;++n) {
b=0; $0=m[n];
for(i=1;i<=NF;i++) b+=--a[$i]
if (!b) { print }
}
}' <file>
这会输出预期的:
6
8
9
12
20
35
如果你想要删除所有包含一个数字的行,这些数字在文件中显示的更多,那么你只需:
$ awk '(NR==FNR) { for(i=1;i<=NF;i++) a[$i]++; next }
{ b=1; for(i=1;i<=NF;i++) b = b && (a[$i]==1) }
b' <file> <file>
来自您输入的 注意:您可能还会遇到Windows \r
问题,因此您可能希望在所有内容之前执行gsub("\r","")
。
答案 3 :(得分:1)
awk中的另一个,处理数据一次:
awk '
{
for(i=1;i<=NF;i++) { # process numbers in record
r[$i]=r[$i] NR OFS # add NR on a record list array
if(p=split(r[$i],t)>1) { # if there are more than one record in r
for(j in t) # delete records on the list
delete a[t[j]]
f=1 # flag up
}
}
if(f=="") # if flag is down
a[NR]=$0 # store current record
f="" # reset flag
}
END {
for(i=1;i<=NR;i++) # in the end
if(i in a) # print all records stored
print a[i]
}' file
35
修订版:
awk '
{
for(i=1;i<=NF;i++) {
if($i in r) { # just store the NR of last duplicate
delete a[r[$i]]
f=1
}
r[$i]=NR
}
if(f=="")
a[NR]=$0
f=""
}
END {
for(i=1;i<=NR;i++)
if(i in a)
print a[i]
}' file
35
答案 4 :(得分:0)
您可以尝试这样的事情:
cat yourFile | tr ' ' '\n' | sort | uniq -u