Shell-Script

UNIX - 將文件拆分為多個文件的命令,列中每 3 個唯一值的所有行

  • August 23, 2017

考慮下面的輸入文件。輸入文件:

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

引用自:https://unix.stackexchange.com/questions/387634