a.txt
cat a.txt
a
b
x
c
b.txt
cat b.txt
d
e
a
f
キュー:
SOMEMAGICK *.txt
a
尋ねる:すべての* .txtファイルの行のみを表示する方法は?
答え1
どうですか?
cat *.txt | sort | uniq -c | egrep "^ +$(ls -1 *.txt | wc -l) "
その後、発生回数を減らすために追加できます。
cat *.txt | sort | uniq -c | egrep "^ +$(ls -1 *.txt | wc -l) " | sed -re 's/^ +[0-9]+ //'
@Stephaneのコメントによると、単一のファイルに1行が複数回表示されると、上記の内容は機能しません。これを防ぐために、最初に各ファイルを並べ替えて一意化します。
for f in *.txt; do sort -u $f > $f.uniqd; done
cat *.uniqd | sort | uniq -c | egrep "^ +$(ls -1 *.uniqd | wc -l) " | sed -re 's/^ +[0-9]+ //'
今はもう行ではありませんが。 :)
答え2
awk 'FNR == 1 { FILENUM++ }
SEEN[$0] == FILENUM - 1 { SEEN[$0] = FILENUM }
END { for (s in SEEN) if (FILENUM == SEEN[s]) print s }' *.txt
説明する
各ファイルの最初の行を読み取るときにFILENUM
読み込むときN最初のファイルFILENUM
はN。
各行を読み取るときに見たファイルの数を数えます(ただし、以前のすべてのファイルで見た場合にのみこれを行う必要があります)。
読み取る入力がない場合は、すべてのファイルに表示されているすべての行を印刷します。
警告する:ここで公開されているいくつかのソリューションと同様に、このソリューションにも弱点があります。質問によると、入力ファイルが空の場合は、次のものが必要です。出力がまったくありません。しかし、awkはライン指向のツールなので、空のファイルを無視します。つまり、空のファイルではFNR == 1 { FILENUM++ }
増やすことはできません。FILENUM
GNU awkを使用すると、次のコマンドを使用してこのエラーを修正できます。ARGIND
組み込み変数
gawk 'SEEN[$0] == ARGIND - 1 { SEEN[$0] = ARGIND }
END { for (s in SEEN) if (ARGIND == SEEN[s]) print s }' *.txt
答え3
GNU awkの使用
awk '{
x[$0][FILENAME]
}
END{
num_files=ARGC-1;
for (b in x)
if (length(x[b]) == num_files)
print b
}' a.txt b.txt c.txt
答え4
私はより簡単なソリューションを使用することを好みますjoin
。
join <(sort a.txt) <(sort b.txt)
これは両方の入力ファイルで機能しますが、空白を含む行では期待どおりに機能しない可能性があり、重複した行が複数回出力されます。
2番目の問題を解決するには、
join <(sort a.txt) <(sort b.txt) | uniq
1つ目はもう少し複雑ですが、-t
発生しない文字をフィールド区切り文字として使用して、flagsで少しトリックを書きました。
$ cat a.txt
This test
foo bar
does work
$ cat b.txt
This is a test
foo does not work
does work
$ join <(sort a.txt) <(sort b.txt) | uniq
does work work
foo bar does not work
This test is a test
$ join -t : <(sort a.txt) <(sort b.txt) | uniq
does work