Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Awk 将textblock中的第一行与块中的下一行合并_Awk_Sed - Fatal编程技术网

Awk 将textblock中的第一行与块中的下一行合并

Awk 将textblock中的第一行与块中的下一行合并,awk,sed,Awk,Sed,我一直在想如何使用awk或sed将文本块中的第一行与块中的每一行合并。每个块由2条或多条线组成,例如: AA 1 BB 2 3 4 CC 5 6 7 8 如何将其合并到以下输出中: AA 1 BB 2 BB 3 BB 4 CC 5 CC 6 CC 7 CC 8 非常感谢您的帮助。假设POSIX符合awk和shell*,这将起作用 awk '/^[[:space:]]*$/ {a=""} {if (a=="") {

我一直在想如何使用awk或sed将文本块中的第一行与块中的每一行合并。每个块由2条或多条线组成,例如:

AA  
1  

BB  
2  
3  
4  

CC  
5  
6  
7  
8  
如何将其合并到以下输出中:

AA 1  
BB 2  
BB 3  
BB 4  
CC 5  
CC 6  
CC 7  
CC 8  

非常感谢您的帮助。

假设POSIX符合awk和shell*,这将起作用

awk '/^[[:space:]]*$/ {a=""} {if (a=="") {a=$0} else print a,$0}'
解释其工作原理(更新):

有两种行动。第一个对空行(可选空白除外)作出反应,因为它前面有以下模式:
/^[:space:]*$/
。当然,斜线只是界定了模式。插入符号(
^
)与行首匹配,美元符号(
$
)与行尾匹配。这将强制匹配整行(否则,此模式将完全匹配任何一行,因为每个可能的输入行都包含零个或多个空格字符)
[[:space:]*
匹配预定义的空白字符字符类中的零个或多个(
*
)字符。此模式的操作将变量(无意义地命名为
a
)重置为空字符串。这用于检测下一个文本块的开头

第二个操作没有模式,因此对每个输入行执行一次。它检查是否已设置前缀(同样,变量
a
),以及:

  • 如果没有,则将前缀设置为当前行的内容(
    $0
    )。(请注意,这也会在空行上执行。)
  • 如果有,则打印前缀,后跟当前行的内容。(
    awk
    由于使用逗号而自动插入空格。)
具有讽刺意味的是,我在编写此更新时发现了一个bug:只包含空格的行将被接受为前缀。这是因为在这种情况下,如果(a==“”)检查失败。有多种方法可以解决这个问题。我对
awk
了解不够,无法推荐一种特定的方法,但这似乎可以做到:

awk '/^[[:space:]]*$/ {s=1;a=""} {if (s==0 && a=="") a=$0; else print a,$0; s=0}'
*)我最初(并且懒洋洋地)写了“GNUawk和bash”,只是因为这是我用于测试的东西。Ed Morton指出,我的解决方案不使用任何工具。

另一个awk

$ cat pckh.txt
AA
1

BB
2
3
4

CC
5
6
7
8

$ awk ' NF && !/[A-Z]/ { print prev,$0 } /[A-Z]/ {  prev=$0 }  ' pckh.txt
AA 1
BB 2
BB 3
BB 4
CC 5
CC 6
CC 7
CC 8

$
$awk-vrs='{for(i=2;iGNU-sed:

$ sed -rn '/^\s*$/{s/.*//;h;be};/./{x;/./!be;x;G;s/(.*)\n(.*)/\2 \1/p};:e' file
AA 1
BB 2
BB 3
BB 4
CC 5
CC 6
CC 7
CC 8
仅将空格/制表符行也视为空行。
如果没有此类行,则可以缩短:

sed -rn '/^$/{h;be};/./{x;/./!be;x;G;s/(.*)\n(.*)/\2 \1/p};:e'

您好!您到底遇到了什么问题?您尝试了什么?谢谢!这正是我要寻找的。我对使用awk非常陌生,您可以添加一些关于代码的解释吗?您的脚本中没有特定于GNU awk或bash的内容。它在任何shell中的任何POSIX awk都会表现相同。
sed -rn '/^$/{h;be};/./{x;/./!be;x;G;s/(.*)\n(.*)/\2 \1/p};:e'