的所有線路中常見的元素我有這樣一個文本文件:查找文本文件
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