複数のファイル(30000行と32列の約20ファイル)があり、同じ文字列で始まる行のみを保持する必要があります。私はこれらのケースが私が必要とするものと非常に似ていることを知っていましたが、どのように適用するのかわかりません。
2つの異なる列を使用して複数のファイル(2つ以上)を比較します。
2つの異なるファイル内の2つの列の値を比較し、差の絶対値が小さい最大値より小さい行全体をエコーする方法は?
私の場合、各ファイルの最初の列は12文字の文字列で構成されていますが、すべてのファイルに存在する文字列で始まる行だけを保持してください。 (入力ファイルごとに1つのファイル、または上記のように1つの出力ファイルも機能します)。私のファイルは次のとおりです。
ファイル1:
-13 -5 0 19.3769 46.9197 1
-13 -4 -2 347.911 57.7232 1
-13 -4 -1 38.5696 39.0027 1
-13 -4 0 2227.39 124.894 1
-13 -3 -3 113.001 40.2117 1
-13 -3 -2 850.847 78.2881 1
ファイル2:
-13 -5 0 2.19085 50.4632 1
-13 -4 -2 283.628 56.7731 1
-13 -4 -1 41.179 48.6423 1
-13 -4 0 1753.54 125.88 1
-13 -3 -3 28.2363 40.6518 1
-13 -3 -2 562.736 66.0301 1
-13 -3 -1 750.747 77.2795 1
出力ファイル1:
-13 -5 0 19.3769 46.9197 1
-13 -4 -2 347.911 57.7232 1
-13 -4 -1 38.5696 39.0027 1
-13 -3 -3 113.001 40.2117 1
-13 -3 -2 850.847 78.2881 1
出力ファイル2
-13 -5 0 2.19085 50.4632 1
-13 -4 -2 283.628 56.7731 1
-13 -4 -1 41.179 48.6423 1
-13 -3 -3 28.2363 40.6518 1
-13 -3 -2 562.736 66.0301 1
答え1
1つのアプローチは、最初に複数のファイルにある12個の初期文字セットをすべて見つけることです。
cut -c-12 file* | sort | uniq -c
上記のコマンドは、cut
名前で始まる各ファイルの最初の12文字を印刷し、文字を並べ替え、各行file
で見つかった回数を追加しますuniq -c
。サンプルファイルでこのコマンドを実行すると、次のものが返されます。
$ cut -c-12 file* | sort | uniq -c
1 -13 -3 -1
2 -13 -3 -2
2 -13 -3 -3
2 -13 -4 0
2 -13 -4 -1
2 -13 -4 -2
2 -13 -5 0
したがって、最初の行を除くすべての行が両方のファイルに表示されます。これで、必要な回数(あなたの場合は20回)だけ発生する行だけを維持してください。
cut -c-12 file* | sort | uniq -c | rev | sed -n 's/ 20 *$//p' | rev
rev
逆に印刷するだけです。ここでは、各行の最後のフィールドが表示された回数を計算するために使用しています。その後、それを渡し、sed
スペース、20、および0以上のスペースで終わる行のみを印刷するように指示します。これにより、20回表示される行だけが保持され、ついにrev
元の形式に戻ります。
これで、grep
検索する文字列のリストにコンテンツ全体を渡すことができます。
$ grep -f <(cut -c-12 file* | sort | uniq -c |
rev | sed -n 's/ 20 *$//p' | rev) file*
-13 -5 0 19.3769 46.9197 1
-13 -4 -2 347.911 57.7232 1
-13 -4 -1 38.5696 39.0027 1
-13 -4 0 2227.39 124.894 1
-13 -3 -3 113.001 40.2117 1
-13 -3 -2 850.847 78.2881 1
シェルがその<()
形式をサポートしていない場合は、結果をcut
別のファイルに保存して使用するか、ループで実行できます。
cut -c-12 file* | sort | uniq -d |
while IFS= read -r l; do grep -- "^$l" file1; done
各ファイルの出力を別々のファイルに入れるには、次のようにします。
cut -c-12 file* | sort | uniq -c | rev | sed -n 's/ 20 *$//p' | rev > list
for f in file*; do grep -f list "$f" > "$f.new"; done