Shell-Script
UNIX - 將文件拆分為多個文件的命令,列中每 3 個唯一值的所有行
考慮下面的輸入文件。輸入文件:
C1|C2|C3|C4|C5|C6 0|1|2|3|0-1-2-3|4 0|2|2|4|0-1-2-3|5 0|1|2|3|1-3-2-4|4 0|1|2|3|1-1-3-4|4 0|1|2|3|1-1-3-4|5 0|1|2|3|4-5-2-6|4 0|1|2|3|4-5-2-6|6 0|4|5|3|7-4-2-4|4 0|1|2|3|7-4-2-5|4 0|1|2|3|7-4-2-5|5 0|1|2|3|7-4-2-5|6 0|1|2|3|7-5-2-6|5
基於欄位 5,例如第一條記錄中的 0-1-2-3,輸出拆分文件預計如下拆分文件 1:
C1|C2|C3|C4|C5|C6 0|1|2|3|0-1-2-3|4 0|2|2|4|0-1-2-3|5 0|1|2|3|1-3-2-4|4 0|1|2|3|1-1-3-4|4 0|1|2|3|1-1-3-4|5
拆分文件 2:
C1|C2|C3|C4|C5|C6 0|1|2|3|4-5-2-6|4 0|1|2|3|4-5-2-6|6 0|4|5|3|7-4-2-4|4 0|1|2|3|7-4-2-5|4 0|1|2|3|7-4-2-5|5 0|1|2|3|7-4-2-5|6
拆分文件 3:
C1|C2|C3|C4|C5|C6 0|1|2|3|7-5-2-6|5
根據第 5 列,對於列中的每 3 個唯一值,文件應該被拆分,甚至應該包含重複第 5 列值的所有行。有人可以幫我弄這個嗎?
awk 的工作。就像是:
awk -F'|' -v fileformat="/abc/output/file_%04d.txt" -v max=3 -v field=5 ' NR == 1 {header = $0; next} ! ($field in seen) { seen[$field] if (++n % max == 1) { close(out) out = sprintf(fileformat, ++f) print header > out } } {print > out}' < /abc/input/a.txt
awk解決方案:
awk -F'|' 'NR==1{ h=$0; f=0; c=1 }NR>1{ a[$5]; if(length(a)>3) { f=0;c++; delete a }; fn="file"c".txt"; if(!f) print h > fn; print > fn; f++ }' file
h=$0
-標題行f=0
- 指向將標題行列印到下一個新文件的時刻的標誌c=1
- 文件名後綴(每個新文件遞增)a[$5]``a
-具有第 5 個欄位的唯一值的索引數組if(length(a)>3) { f=0;c++; delete a }``c++
-在成功 3 個唯一值時啟動下一個新文件名 ( )。(delete a
- 從數組中刪除所有項目a
)fn="file"c".txt"
- 目前文件名查看結果:
for f in file[0-9]*.txt; do echo "$f"; cat "$f"; echo; done
輸出:
file1.txt C1|C2|C3|C4|C5|C6 0|1|2|3|0-1-2-3|4 0|2|2|4|0-1-2-3|5 0|1|2|3|1-3-2-4|4 0|1|2|3|1-1-3-4|4 0|1|2|3|1-1-3-4|5 file2.txt C1|C2|C3|C4|C5|C6 0|1|2|3|4-5-2-6|4 0|1|2|3|4-5-2-6|6 0|4|5|3|7-4-2-4|4 0|1|2|3|7-4-2-5|4 0|1|2|3|7-4-2-5|5 0|1|2|3|7-4-2-5|6 file3.txt C1|C2|C3|C4|C5|C6 0|1|2|3|7-5-2-6|5