如何使用awk或sed将两条线合并到一个准确的位置,就像它被上拉/下拉一样
这里给出了我的文件的输出示例如何使用awk或sed将两条线合并到一个准确的位置,就像它被上拉/下拉一样,awk,sed,gawk,Awk,Sed,Gawk,这里给出了我的文件的输出示例 ! S R Number : Class : ! 635035 3 ! Name : ! ADAM BASHA +========================================+ ! Code ! Descrip
! 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 !
这个文件太大了,所以我贴了一个样本。此输出文件似乎将一些行拆分为两行,例如包含编号、名称和应付净额的行。请提供一个解决方案
已经给出的答案很好,唯一的问题是它们处理所有的行,而不是只处理分割的行。谢谢大家
我已经用一个实际的例子编辑了我的问题。这个(不是很优雅的)命令应该可以完成输入文件测试的工作:
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
这个(不是很优雅的)命令应该对输入文件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
另一个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
$awk'开始{OFS=FS=”“}
{如果(NR%2)分割($0,p);
else{for(i=1;i另一个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
$awk'开始{OFS=FS=”“}
{如果(NR%2)分割($0,p);
else{for(i=1;i这可能适合您(GNU-sed):
该过程结合了所需的行,并使用了唯一的标记(换行符)从左向右移动,比较标记后面的单个字符。如果第一行不是空格,则保留它并将标记前进到其上方。否则,将第一行替换为第二行,并将标记前进到其上方。如果标记已到达行尾,则移除标记,但第一行短于第二行的情况除外在第一行引入了可选空间。这可能适合您(GNU-sed):
该过程结合了所需的行,并使用了唯一的标记(换行符)从左向右移动,比较标记后面的单个字符。如果第一行不是空格,则保留它并将标记前进到其上方。否则,将第一行替换为第二行,并将标记前进到其上方。如果标记已到达行尾,则移除标记,但第一行短于第二行的情况除外第一行引入了可选空格。缩进背后的原因是什么?更好?缩进的目的是条件{action}
块在动作处对齐,相同级别的语句在相同级别缩进。如果它在行中流动并且很短(如If(x))y
保持一致。我没有漂亮的打印机,有时会出错……我希望这能有所帮助。顺便说一句,我也没有漂亮的打印机。我是漂亮的打印机;)太多的花括号符合我的口味,awk--profile
会给你更好的代码,如果你愿意的话,但是我喜欢更密集的一行样式。不,不,不。这不是喜欢与否。这是关于坚如磐石的、可读的和可维护的代码。虽然我同意对于一行习惯用法来说规则有点不同,但上面的代码显然不是一行习惯用法和你的缩进风格使它难以阅读、获取和维护。你从不放置内联注释的事实可能是你缩进“风格”的另一个结果。缩进背后的原因是什么?更好?缩进的目的是条件{action}
块在动作中对齐,相同级别的语句在相同级别的缩进中。如果它在一行中流动并且很短(比如If(x)y
保持在同一行。我没有漂亮的打印机,有时会出错……我希望这会有所帮助。顺便说一句,我也没有漂亮的打印机。我是漂亮的打印机;)太多的花括号符合我的口味,awk--profile
会给你更好的代码,如果你愿意的话,但是我喜欢更密集的一行样式。不,不,不。这不是喜欢与否。这是关于坚如磐石的、可读的和可维护的代码。虽然我同意对于一行习惯用法来说规则有点不同,但上面的代码显然不是一行习惯用法和你的缩进风格使它很难阅读、获取和维护。你从不放置内联注释的事实可能是你缩进“风格”的另一个结果。odd
可以写成NR%2
odd
可以写成NR%2
你不应该做的事情更多:-).awk用于操作text.period.full stop。如果您想执行其他操作(移动文件?终止进程?),则应使用其他操作(例如shell)。提供的所有解决方案都很好,但文件中的所有行都在处理中。我只需要合并两行,一行有名称,另一行有实际名称,如问题所述。我在文件中有很多这样的情况。我需要合并具有上述两种模式的两行。谢谢大家解决方案。@EdMorton,我已经编辑了我的问题,并在我的要求中提供了更具代表性的示例输入/输出。非常好的解决方案,先生。非常感谢@Edmortony您的欢迎。如果/当您准备接受解决方案时,请记住单击它旁边的复选标记。请参阅。这是您不应该做的更多事情:-).awk用于操作text.period.full stop。如果您想执行其他操作(移动文件?终止进程?),则应使用其他操作(例如shell)。提供的所有解决方案都很好,但文件中的所有行都在处理中。我只需要合并两行,一行有名称,另一行有实际名称,如问题所述。我在文件中有很多这样的情况。我需要合并具有上述两种模式的两行。谢谢大家解决方案。@EdMorton,我已经编辑了我的问题,并在我的要求中提供了更具代表性的示例输入/输出。非常好的解决方案,先生。
$ 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
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