最近在做一個事情,需要將一個文本文件按照行數進行切割,然后用了,awk的方法,感覺很好用, 記錄一下。
腳本如下:
#!/bin/bash ## 文件效果: 根據行數來切割文件 ## 參數1為要切割的文件名 ## 參數2為每個切割后文件的行數 filename=$1 fileline=$2 echo "filename=$filename" echo "fileline=$fileline" awk -v count=$fileline 'BEGIN{i=0} { print $0 > sprintf("%s_%d",FILENAME,i) ; if (NR>=(i+1)*count) { close(sprintf("%s_%d",FILENAME,i)); i++;} }' $filename echo "=====finish====="
簡單解釋一下, 比較重要的就是那一行awk
-v count=$fileline , -v 用來將變量傳入
BEGIN中用來初始化一個變量 i, 用來記錄是否需要進行換文件, 之后將每一行輸入到對應的文件中,
直到 NR>=(i+1)*count , 相當於一個文件已經寫完了, 需要寫入下一個文件。
這里需要做兩件事情,先關閉之前寫的文件, 如果不關閉, 會報錯 awk: xxx makes too many open files , 這個表示awk 打開的文件太多了。
然后將計數器加1, 這樣就可以寫入下一個文件了。
運行效果,就是將 filename 切割成 filename_0 , filename_1, filename_2 等多個文件, 每個文件都是 fileline 行, 最后一個文件,就是剩下的行數。
可以很簡單的得到下面這個變種, 就是 根據想要切割的文件數量來進行按照行數切割。
#!/bin/bash ## 根據文件數來切割 ## 參數1為要切割的文件名 ## 參數2為期望得到的文件數 filename=$1 filenum=$2
# 計算每個文件的行數
fileline=$(( `cat $filename | wc -l ` / $filenum + 1 )) echo "filename=$filename" echo "filenum=$filenum" awk -v count=$fileline 'BEGIN{i=0} { print $0 > sprintf("%s_%d",FILENAME,i) ; if (NR>=(i+1)*count) { close(sprintf("%s_%d",FILENAME,i)); i++;} }' $filename echo "=====finish====="