我在论坛上找不到这个案例,所以才来提问。
这是输入文件:
module
x(a,b,c)
module
y(d,e,f,
g,h,i)
module
z(j,k,l)
输出文件应该是:
module x(a,b,c)
module y(d,e,f,
g,h,i)
module z(j,k,l)
答案1
您要做的是将这些module
行与下一行连接起来。
使用sed
:
$ sed '/^module/N;s/\n//' file
module x(a,b,c)
module y(d,e,f,
g,h,i)
module z(j,k,l)
这是按原样复制和粘贴数据的情况,每行末尾都有空格。
该sed
命令将在读取时打印每一行,但是当它遇到以 string 开头的行时module
,它会在下一行之间附加嵌入的换行符(这就是所做的N
)。在打印结果之前,我们通过替换删除换行符。
如果您的数据行尾没有空格,请使用
$ sed '/^module/N;s/\n/ /' file
module x(a,b,c)
module y(d,e,f,
g,h,i)
module z(j,k,l)
以防万一您想要这个(假设输入行末尾没有空格):
$ sed -e '/^module/bpp' -e 'H;$bpp' -e 'd' \
-e ':pp' -e 'x;/^$/d;s/\n/ /g' file
module x(a,b,c)
module y(d,e,f, g,h,i)
module z(j,k,l)
带注释的sed
脚本:
/^module/ b print_previous; # print previous record
H; # append this line to hold space
$ b print_previous; # print previous (last) record
d; # end processing this line
:print_previous; # prints a record accumulated in the hold space
x; # swap in the hold space
/^$/ d; # if line is empty, delete it
s/\n/ /g; # replace embedded newlines by spaces
# (implicit print)
奖励ed
内容:
$ printf '%s\n' 'g/^module/ j' ,p Q | ed -s file
module x(a,b,c)
module y(d,e,f,
g,h,i)
module z(j,k,l)
上面的代码将从字符串开始的任何行module
与其下一行连接起来。
$ printf '%s\n' 'v/^module/ -,.j' ,p Q | ed -s file
module x(a,b,c)
module y(d,e,f, g,h,i)
module z(j,k,l)
上面连接任意行不是module
从字符串开始以前的线。
答案2
使用 awk:
~ awk '/^module/ {l = $0; getline; printf "%s", l} 1' input-file
module x(a,b,c)
module y(d,e,f,
g,h,i)
module z(j,k,l)
对于以 开头的每一行module
,将该行保存在 中l
,移动到下一行 ( getline
),然后打印保存的行(不带换行符)。然后打印每一行。
答案3
另一种选择:创建ed
脚本!
首先预先计算所需的连接数量;然后,它生成一定数量的ed
搜索和连接命令,并将它们以及最后的保存和退出通过管道传输到ed
:
#!/bin/bash
n=$(grep -c '^module *$' input)
{
for((i=1; i <= n; i++))
do
printf '/^module *$/\n.,+1j\n'
done
echo w
echo q
} | ed -s input >/dev/null
答案4
使用乐(以前称为 Perl_6)
~$ raku -ne '/^module/ ?? (print "$_\t"; put get) !! .put;' file
或者:
~$ raku -ne '/^module/ ?? (put join "\t", $_, lines[0]) !! .put;' file
awk
上面的 Raku 答案与@muru 的优秀答案类似。在 Raku 中,三元运算符的拼写为测试 ??
真的 !!
错误的。这些-ne
标志按行读取文件而不自动打印。
如果该行以 ed 开头module
,print
则后跟一个\t
制表符(可以用任何列分隔符替换)。然后(在第一个示例中)代码指示get
下一行及其put
内容。在第二个示例中,您打印$_
主题变量,并将下一行line[0]
加入\t
并退出put
它。如果没有匹配module
(即“False”),则该行简单地退出put
。
输入示例(行尾已清理):
module
x(a,b,c)
module
y(d,e,f,
g,h,i)
module
z(j,k,l)
示例输出(制表符分隔的列):
module x(a,b,c)
module y(d,e,f,
g,h,i)
module z(j,k,l)
请注意,OP 的输入文本包含尾随空格,因此虽然使用原始输入可能没问题,但要连接的其他示例文本文件可能不包含尾随空格,在这种情况下,“列”将一起运行。因此使用\t
上面的方法来间隔列。