すべてのファイルに存在する共通の番号を抽出したい。フォルダに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と記述して比較するだけです。しかし、私はすべてのファイルに共通の番号が存在することを望んでいます。
a.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
他の問題に加えて、スクリプトループがcomm
を10000回呼び出しているため、非常に遅くなっています。より高速な代替方法は、それらすべてをソートして繰り返しをカウントすることです。ファイルの数に等しい数の行がすべてのファイルに存在します(各ファイル内の値が繰り返されていない場合)。
set -- ./*.txt
sort -n "$@" | uniq -c | awk -vcount="$#" '$1==count{print $2}'
私は両方にファイルのリストを持つために位置引数を使用しています"$@"
およびファイルの数$#
。
ソートは数値です-n
numberを要求すると。
次のような番号が繰り返されているファイルがないことをチェック(およびソート)できます。
set -- ./*.txt
for f; do
sort -n "$f" > "$f.tempfile"
mv "$f.tempfile" "$f"
if [ "$(uniq -d "$f")" != "" ]; then echo $f; fi
done
これにより、番号が繰り返されているすべてのファイルが一覧表示され、個々のファイルが並べ替えられます。
問題は、各反復で出力を上書きすることです。 >
リダイレクトは、リダイレクト先のファイルを切り捨て(空)にします。
別のアプローチ:各ファイルをsort -u
で個別に並べ替えて、そのファイルに固有のエントリを取得し、これらの並べ替え操作の結果を連結してsort | uniq -c
に渡し、各エントリの回数の合計を取得します。すべてのファイルに表示されます。次に、その結果を調べて、ファイルの数に等しいカウントを持つエントリを選択します。これらは、すべてのファイルで発生するエントリです。
set -- ./*.txt
for file do
sort -u "$file"
done | sort | uniq -c |
awk -v c="$#" '$1 == c { print $2 }'
ここでは位置パラメーターを使用して、set -- ./*.txt
で反復処理するファイルのリストに設定しています。これは、後で$#
を使用できるようにするためです。これは、リスト内のファイルの数です。
表示する最初の3つのデータセットの場合、これは次のように出力されます。
3
6
7
comm
が複数のファイル間の共通行を正しく報告するためには、入力ファイルがまだソートされていない場合は、ソートされたとおりに渡す必要があることを最初に知ってください。
2つ目は、mv
コマンドをmv final.txt a.txt
に変更する必要があることです。前の試行の結果に対して次のファイルをチェックするため。ここでは、a.txt
からバックアップを取り、代わりにcommon.txt
をforループでの反復に使用しました。
したがって、最終的なスクリプトは次のようになります。
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
は、10000ファイル間で共通の行になります。
comm
は、ソートされたファイル専用です。
sortedファイル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
の代わりに>
演算子を使用することもできます(ファイルへの書き込みと上書き)