複数のファイルで共通の番号を見つける方法は?

複数のファイルで共通の番号を見つける方法は?

すべてのファイルに存在する共通番号を抽出したいと思います。私のフォルダには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.txtcommon.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.txt10,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

これにより、重複した番号を持つすべてのファイルが一覧表示され、個々のファイルが並べ替えられます。

関連情報