すべてのファイルに存在する共通番号を抽出したいと思います。私のフォルダには1000個のファイルがあります。すべてのファイル番号を比較して、1000個のファイルの中で共通の番号を探したいと思います。次のコードを使用しました。
for ((i=2;i<=10000;i++))
do
comm -12 --nocheck-order a.txt "$i".txt > final.txt
mv final.txt file.txt
done
しかし、最後のファイルだけをa.txtで書き直して比較します。しかし、すべてのファイルに汎用番号が存在したいと思います。
.txtファイルがあるとします。
1
3
47
8
6
7
1.txtファイル:
2
3
6
7
8
2.txtファイル:
3
5
6
7
9
3.txtおよび4.txt....1000.txt。これがこの3つのファイルでうまく機能する場合は、すべてのファイルでもうまく機能します。このファイルで一般的に見つかる内容は次のとおりです。
3
7
私に与えられたとき
3
8
3
どうすればいいのか教えてください。
答え1
各数値がファイルに一度だけ現れるとします。
$ awk '{c[$1]++} END{for (i in c) if (c[i] == (ARGC-1)) print i}' a.txt {1..2}.txt
3
6
7
答え2
comm
ソートされたファイルでのみ機能します。
比較するソート済みFILE1 および FILE2 ファイルを 1 行ずつ読み込みます。
源泉:https://linux.die.net/man/1/comm
したがって、このアルゴリズムはソートされていないファイルでは機能しません。これは働きます:
#!/bin/sh
sort -n a.txt > tmp.txt
END=4
for i in `seq 2 $END`
do
comm -12 --nocheck-order tmp.txt $i.txt |tee tmp.txt
done
cp tmp.txt "final.txt"
これに加えて、一部のシステムでは演算子を使用する|tee
こともできます(ファイルに書き込んで上書きする)。>
答え3
最初に知っておくべきことは、comm
複数のファイル間の共通行を正しく報告するには、ソートされた入力ファイルを渡す必要があることです(以前にソートされていない場合)。
mv
次に、以前の試行の結果に基づいて次のファイルを確認するには、コマンドを;に変更する必要があります。mv final.txt a.txt
ここではバックアップを取り、forループで繰り返しましたa.txt
。common.txt
したがって、次の最終スクリプトが生成されます。
cp a.txt common.txt
for ((i=1;i<=10000;i++));
do comm -12 <(sort common.txt) <(sort $i.txt) >temp.txt;
mv temp.txt common.txt;
done
最後は、cat common.txt
10,000個のファイルに共通して現れる行です。
答え4
他の問題の1つは、スクリプトがループcomm
内で10000回呼び出され、非常に遅くなることです。より速い選択肢はすべて整列し、反復回数を計算することです。すべてのファイルにはファイル数と同じ行があります(各ファイル内で値が繰り返されない場合)。
set -- ./*.txt
sort -n "$@" | uniq -c | awk -vcount="$#" '$1==count{print $2}'
場所パラメータを使用してファイルリスト"$@"
とファイル数を取得します$#
。
-n
要求すると、ソートは数字で行われます。数字。
あなたはできます確認する(およびソート済み)ファイルに重複した番号がありません。
set -- ./*.txt
for f; do
sort -n "$f" > "$f.tempfile"
mv "$f.tempfile" "$f"
if [ "$(uniq -d "$f")" != "" ]; then echo $f; fi
done
これにより、重複した番号を持つすべてのファイルが一覧表示され、個々のファイルが並べ替えられます。