Command-Line
比較不同文件之間的列
我有多個文件(大約 20 個文件,30000 行和 32 列),我只需要保留以相同字元串開頭的行。我發現這些案例與我需要的非常相似,但我不知道如何調整它們..
如何比較兩個不同文件中兩列中的值,回顯差異絕對值<一個小的最大值的整行?
在我的情況下,每個文件都有一個由 12 個字元組成的字元串的第一列,我只需要保留以所有文件中都存在的字元串開頭的行。(每個輸入文件一個文件,或者像上述情況下的一個輸出文件也可以)。我的文件是這樣的:
文件 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
一種方法是首先找到存在於多個文件中的所有 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
如果您的 shell 不支持該
<()
格式,您可以將結果保存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