我有一個如下的資料檔案:
>> cat file1.txt
@target G0.S0
1 6
1 4
4 2
@target G0.S0
2 4
8 9
5 7
@target G0.S0
3 5
0 9
3 7
我想在一個新檔案中創建分隔列,@target G0.S0其中列設定在前面的列旁邊,如下所示:
>> cat file2.txt
1 6 2 4 3 5
1 4 8 9 0 9
4 2 5 7 3 7
我在互聯網上搜索,但我沒有得到我想要的。
uj5u.com熱心網友回復:
帶有pr,grep和tail外殼的快速單線。
pr "-$(grep -Fc '@target G0.S0' file1.txt)ts"' ' file1.txt | tail -n 2
將輸出重定向到新檔案。
pr ... > file2.txt
讓我們稍微分解一下。
pr是一個列印實用程式。grep -Fc '@target G0.S0' file1.txt展開為一個數字見:grep --help | grep -E -- ' -(F|c)'$( )稱為命令替換。t并且s是pr查看的選項:pr --help | grep -E -- '^ *-(s|t)'tail從第二行開始列印,請參閱:tail --help | grep -- -n- 最后,命令擴展為:
pr -Nts' ',其中N一個 int/number。
如前所述@Socowi,撰寫時有很多限制。該代碼假設其間@target G0.S0的所有行都相等/相同。(這是我的答案),如果有太多(長資料/輸入)大小,應該添加一個額外的選項,-w. 就像我提到的那樣,如果檔案/資料/大小/輸入很大/很大,那么該awk解決方案是首選。
- 如果資料大小/檔案較大,我會選擇使用
awk。
uj5u.com熱心網友回復:
使用awk,假設 stride 為 4 并命名您的腳本concat并賦予它 exec 權限:
#! /usr/bin/awk -vN=4 -f
(NR-1)%N==0 {next}
{i=int(NR-2)%N;a[i]=(a[i] ? a[i] " " : "") $0}
END {for (i=0; i<N; i ){print a[i]}}
然后
./concat file1.txt > file2.txt
給
1 6 2 4 3 5
1 4 8 9 0 9
4 2 5 7 3 7
在file2.txt
uj5u.com熱心網友回復:
單一awk程式解決方案
以下建議通過參考行號(用于回圈索引 1-3,存盤第 2-4、6-8、10-12 行等,每次連接)索引的陣列中的行累積行。主塊之前的條件不包括第 1、5、9 行等。END 塊迭代陣列以列印重定向到所需新檔案名的輸出。
awk ' (NR-1)%4!=0{lines[(NR-1)%4]=lines[(NR-1)%4]$0}
END{ for(line=1; line<4; line ) {print lines[line]}
} ' file1.txt > file2.txt
uj5u.com熱心網友回復:
這可能對您有用(csplit、paste 和 sed):
csplit -qz --suppress file '/@target/' '{*}' && paste -d' ' xx* |
sed 's/ / /g' >outFile && rm xx*
將輸入檔案拆分為連續編號的檔案,其中包含要附加的每一列的一行。
粘貼中間檔案,用空格分隔。
從上面獲取輸出,洗掉額外的空格,輸出到最終檔案并清理。
一個 GNU sed 唯一的解決方案:
sed -nE '/\n/!{:a;N;$!ba}
s/^@/\n@/;s/\S$/& /mg;tb
:b;s/^([^\n]*)((\n[^@]*)*)\n@[^\n]*\n([^\n] )/\1\4\2\n/;tb
s/ \n/\n/;P;s/\n $//;s/\n\n/\n@\n/g;D' file
如果檔案沒有被 slurp 到模式空間(記憶體)中,slurp 檔案。
在模式空間的開頭引入一個換行符,并在每行的末尾提供一個空格。
遍歷檔案,將標題行后面第一行的值附加到模式空間的第一行。替換每個標題,因為它由兩個換行符處理。
去掉行尾引入的空格,列印模式空間的第一行。
如果所有行都已處理,則模式空間的末尾將僅包含換行符,在這種情況下洗掉它們。
@否則,通過在每次出現的兩個換行符之間插入一個偽標題來重新引入一個偽標題。
如果仍有要處理的行,請洗掉列印的行并再次開始 sed 程序。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/532841.html
標籤:重击sed分裂grep牛
上一篇:在awk模式內的字串中轉義雙引號
