的所有线路中常见的元素我有这样一个文本文件:查找文本文件
a b c d e
b c e
d f g e h c
我要寻找一个简单的AWK可输出忽略了他们的第一个元素的所有行中的共同元素。所需的输出是:
c e
或
e c
的所有线路中常见的元素我有这样一个文本文件:查找文本文件
a b c d e
b c e
d f g e h c
我要寻找一个简单的AWK可输出忽略了他们的第一个元素的所有行中的共同元素。所需的输出是:
c e
或
e c
$ cat tst.awk
FNR==1 { for (i=1; i<=NF; i++) common[$i]; next }
{
for (c in common) {
present = 0
for (i=1; i<=NF; i++) {
if ($i == c) {
present = 1
}
}
if (!present) {
delete common[c]
}
}
}
END {
i=0
for (c in common) {
printf "%s%s", (++i>1?OFS:""), c
}
print ""
}
$ awk -f tst.awk file
c e
如果你真的想跳过在每一行的第一个字符,只是改变2个for (i=1; i<=NF; i++)
环在2,而不是1开始。
尽管上面已经被接受,但我更喜欢@ jaypal的方法(但不是他选择的工具:-)),所以这里是awk的等价物:
$ cat tst.awk
{ delete seen; for (i=1; i<=NF; i++) if (!seen[$i]++) count[$i]++ }
END {
i=0
for (c in count)
if (count[c] == NR)
printf "%s%s", (++i>1?OFS:""), c
print ""
}
$
$ awk -f tst.awk file
c e
如果您的awk不支持delete seen
,请将其更改为split("",seen)
。
perl
救援:
perl -lane '
my %seen;
map { $total{$F[$_]}++ unless $seen{$F[$_]}++ } 1 .. $#F;
}{
print join " ", grep { $total{$_} == $. } keys %total
' file
e c
保持滚动%total
哈希值,只有当他们是每个行独特的,这将增加的元素。 %seen
是一个哈希,帮助跟踪这些元素。因此我们使用my
声明为每一行重置它。
在END
块中,我们只是grep
那些元素的值满足行总数,这意味着它们在每行上都被看到。
的命令行选项有:
-l
:在要吃掉换行符期间print
地方回来。-a
:将空行分割并用这些值加载数组@F
。-n
:创建一个while(<>) { .. }
循环来处理每一行。-e
:执行引号后面的代码块。+1不错!方法被盗,并添加到我的答案awk。如果你想偷回来并添加相当于你的awk,请随意,我会从我的地址中删除它。 – 2014-09-10 23:27:25
@EdMorton即使我尝试了,我也无法让它像你的一样漂亮! ':''适时upvoted! – 2014-09-10 23:30:07
在Perl中抛弃grep或map的结果被认为是不好的形式。你可能会考虑用'(1 .. $#F){$ total {$ F [$ _]} ++ ++,除非$ seen {$ F [$ _]} ++}' – 2014-09-11 13:16:32
另一个perl的方法:
perl -lane '
if ($. == 1) { %intersect = map {$_ => 1} @F; next }
%intersect = map {$_ => 1} grep {$intersect{$_}} @F;
END {print join " ", keys %intersect}
' file
结果将不会在任何特定的顺序。
如果第2行包含“d”会怎么样? – 2014-09-10 22:24:16