我有一個 file1 看起來像這樣
25 104.601 0.5
24.8488 104 0.5
24.5341 103 0.5
24.1844 102 0.5
24.1568 101 0.5
24.1568 100 0.5
24.1844 99 0.5
24.5341 98 0.5
我需要找到第 1 列的最小值並將其列印在另一個檔案中_NEW
現在我需要對不同的文件重複上述操作並找到至少 100 個文件的最小值..
這樣我就可以在 file_NEW 中得到像這樣的最終輸出
24.1568
23.3254 (from file2)
22.312 (from file3)
.....
這裡,file2 和 file3 具有與 file1 相似的資料集。所有輸入檔案都具有相同的名稱模式,例如 file*.txt 並且位於同一目錄中
誰能建議如何使用 awk 或 sed 來做到這一點?
謝謝
答案1
要查找最小值,我們可以使用以下命令
對每個文件使用以下命令
awk 'NR==1{sum=$1}($1 < sum){sum=$1}END{print sum}' filename >> outputfile
測試並運行良好
答案2
awk '{print $1 "\t(from " FILENAME ")"}' file* | sort -k1,1n | awk -F'\t' '!seen[$2]++'
上述內容將使用標準 UNIX 工具一次穩健且有效率地處理所有輸入文件,例如:
$ cat file1
25 104.601 0.5
24.8488 104 0.5
24.5341 103 0.5
24.1844 102 0.5
24.1568 101 0.5
24.1568 100 0.5
24.1844 99 0.5
24.5341 98 0.5
$ cat file2
75 104.601 0.5
74.8488 104 0.5
74.5341 103 0.5
74.1844 102 0.5
74.1568 101 0.5
74.1568 100 0.5
74.1844 99 0.5
74.5341 98 0.5
$ awk '{print $1 "\t(from " FILENAME ")"}' file{1,2} | sort -k1,1n | awk -F'\t' '!seen[$2]++'
24.1568 (from file1)
74.1568 (from file2)
但假設您的檔案名稱都不包含製表符或換行符號。如果它們確實包含選項卡,則可以透過簡單的調整來處理它們:
awk '{print $1 "\t(from " FILENAME ")"}' file* |
sort -k1,1n |
awk '{f=$0; sub(/[^\t]*\t/,"",f)} !seen[f]++'
但如果它們也包含換行符,那麼您需要 GNU 工具來容納\0
(NUL) 終止符:
awk -v ORS='\0' '{print $1 "\t(from " FILENAME ")"}' file* |
sort -z -k1,1n |
awk -v RS='\0' '{f=$0; sub(/[^\t]*\t/,"",f)} !seen[f]++'
答案3
sed
厭惡
find . -name "file*" -exec sh -c '
echo $(sort -nk1 "$1" | sed -n "1{s/ .*//p}" )" (from "${1##*/}")" ' sh {} \; | sort -nk1 > output.txt; cat output.txt
sort
如果需要的話輸出檔案並新增檔案名
答案4
IIUC,您希望每個文件上都有這個:
awk 'NF' FILE | sort -n -k1 - | awk 'NR==1{print $1}' >> file_NEW
awk 'NF' FILE
如果輸入檔中有空行,則需要使用首字母。您沒有指定是否要以遞歸方式或非遞歸方式對給定目錄中的所有檔案執行此命令,還是僅對名稱中具有特定模式的某些檔案執行此命令。無論如何,您可以使用find
以下方法來做到這一點:
find . -name "FILE*" -exec sh -c 'awk "NF" FILE | sort -n -k1 - | awk "NR==1{print \$1}" >> file_NEW' sh {} \;
在這種情況下,上述命令將對給定目錄中名稱以FILE
.
另請注意,這不一定會在輸出中提供排序列表,file_NEW
因為會盲目地 在找到的每個文件上find
運行所有內容。-exec