我的文件的示例输出在这里给出
! S R Number : Class : !
635035 3
! Name : !
ADAM BASHA
+========================================+
! Code ! Description ! Amount !
+========================================+
! 2222 ! Tech.Exam Allow ! 340.00 !
! 3104 ! D A ! 19,524.43 !
! 3107 ! H R A ! 3,984.40 !
! 4113 ! Transport Allow ! 460.00 !
! : !
Net Amount Payable : 24,308.83
! S R Number : Class : !
551820 2
! Name : !
TOM SMITH
+========================================+
! Code ! Description ! Amount !
+========================================+
! 3104 ! D A ! 19,404.41 !
! 3107 ! H R A ! 3,960.60 !
! 4113 ! Transport Allow ! 460.00 !
! : !
Net Amount Payable : 23,825.01
! S R Number : Class : !
550044 3
! Name : !
ROBERT LOUIS
我想要将与下面给出的这种格式类似的每两行合并为
! S R Number : Class : !
635035 3
我想要将两行合并如下
! S R Number : 635035 Class : 3 !
整个结果应如下:
! S R Number : 635035 Class : 3 !
! Name : ADAM BASHA !
+========================================+
! Code ! Description ! Amount !
+========================================+
! 2222 ! Tech.Exam Allow ! 340.00 !
! 3104 ! D A ! 19,524.43 !
! 3107 ! H R A ! 3,984.40 !
! 4113 ! Transport Allow ! 460.00 !
! Net Amount Payable : 24,308.83 !
! S R Number : 551820 Class : 2 !
! Name : TOM SMITH !
+========================================+
! Code ! Description ! Amount !
+========================================+
! 3104 ! D A ! 19,404.41 !
! 3107 ! H R A ! 3,960.60 !
! 4113 ! Transport Allow ! 460.00 !
! Net Amount Payable : 23,825.01 !
! S R Number : 550044 Class : 3 !
! Name : ROBERT LOUIS !
文件太大,所以我发布了一个样本。此输出文件似乎将某些行拆分为两行,如包含S R Number, Name and Net Amount Payable
的行。请提供解决方案。
已经给出的答案工作正常,唯一的事情是它们处理所有行而不是仅处理分割的行。谢谢大家。
我使用实际例子编辑了我的问题。
答案 0 :(得分:3)
$ cat tst.awk
/^[^[:space:]]/ {
if (NR>1) { print buf }
buf = $0
next
}
{
if (/:/) { sub(/:/," ",buf) }
while ( match($0,/[^[:space:]]+/) ) {
buf = substr(buf,1,RSTART-1) substr($0,RSTART,RLENGTH) substr(buf,RSTART+RLENGTH)
$0 = sprintf("%*s",RSTART+RLENGTH-1,"") substr($0,RSTART+RLENGTH)
}
}
END { print buf }
$ awk -f tst.awk file
! S R Number : 635035 Class : 3 !
! Name : ADAM BASHA !
+========================================+
! Code ! Description ! Amount !
+========================================+
! 2222 ! Tech.Exam Allow ! 340.00 !
! 3104 ! D A ! 19,524.43 !
! 3107 ! H R A ! 3,984.40 !
! 4113 ! Transport Allow ! 460.00 !
! Net Amount Payable : 24,308.83 !
! S R Number : 551820 Class : 2 !
! Name : TOM SMITH !
+========================================+
! Code ! Description ! Amount !
+========================================+
! 3104 ! D A ! 19,404.41 !
! 3107 ! H R A ! 3,960.60 !
! 4113 ! Transport Allow ! 460.00 !
! Net Amount Payable : 23,825.01 !
! S R Number : 550044 Class : 3 !
! Name : ROBERT LOUIS !
答案 1 :(得分:1)
使用一个字符长度字段的另一个gawk
解决方案
$ awk 'BEGIN{OFS=FS=""}
{if(NR%2) split($0,p);
else {for(i=1;i<=NF;i++) if($i==" ") $i=p[i];
print}}' file
Name : Adam Basha Class :3
这里假设第二条记录长于第一条记录(如果没有将循环结束条件更改为最大长度(p)和NF或之后附加额外记录。
答案 2 :(得分:0)
这个(不是很优雅)命令应该为输入文件test
执行工作:
awk 'BEGIN{odd=1}
odd{line=$0;odd=0;next}
{odd=1;nline=""
for(i=1; i<=length($0);i++){
nline=substr($0,i,1)==" " && i <= length(line)? nline""substr(line,i,1) : nline""substr($0,i,1)
}
print nline
}' test
输出:
Name : Adam Basha Class : 3
答案 3 :(得分:0)
这可能适合你(GNU sed):
sed -r 'N;/\n\s/!{P;D};s/^/\n/;ta;:a;/\n.*\n$/s/\n//g;t;s/\n\n/\n \n/;s/\n(\S)(.*)\n./\1\n\2\n/;ta;s/\n.(.*)\n(.)/\2\n\1\n/;ta' file
该过程组合了所需的线条并使用从左向右移动的唯一标记(换行符),比较标记后面的单个字符。如果第一个不是空格,请保留它并将标记推到它上面。否则,将第一个替换为第二个并将标记推进其上。如果标记已到达行尾,则在第一行引入额外空格时除去第一行短于第二行的标记。