我有文件.txt
john,
5901,
open
lina,
2401,
open
jody,
5401,
open
我想在每一行最后插入一个新行,结果应该是:
john,5901,open
lina,2401,open
jody,5401,open
我尝试什么
cat file.txt | tr -d '\n'
但结果是这样的
john,5901,openlina,2401,openjody,5401,open
答案1
使用 awk 中段落模式:
$ awk -vRS= -vOFS= '{$1=$1} 1' file.txt
john,5901,open
lina,2401,open
jody,5401,open
取消设置记录分隔符RS=
会使 awk 将空行之间的所有内容视为单个记录,并将换行符添加到空白输入字段分隔符的默认列表中。由于您的输入不包含其他空格,这意味着块的每一行都成为一个字段。然后,我们通过为自身重新分配字段值来强制记录重新评估,最后使用空的输出字段分隔符代替默认的单个空格来$1=$1
打印记录。OFS=
答案2
$ paste -d '\0' - - - - <file
john,5901,open
lina,2401,open
jody,5401,open
通过将输入文件中的每一行放入下一列,将数据重新格式化为四列。各部分之间的空行是第四列,它将放置在每个输出行的最后,但由于它是空的,因此不会包含任何内容。
数据中已经包含逗号,因此我们使用空分隔符paste
(with -d '\0'
)。
使用该方法的解决方案sed
不假设数据分为三行组:
$ sed -n 'H; /^$/{x;s/\n//g;p;d;}; ${x;s/\n//g;p;}' file
john,5901,open
lina,2401,open
jody,5401,open
它通过向保留空间添加行来实现此目的H
,当它遇到空行或文件末尾时,它会删除H
添加的保留空间中嵌入的换行符,并打印结果。
答案3
和awk
awk '{ printf (NF)?$0:RS } END{ print ""}' infile
如果每一行不是空行(包含一组制表符、空格和换行符的行),则将其连接成一行。
该解决方案不依赖于每组中的固定3条线。
对于特定情况,如果您有多个空行并避免结果重复,您可以执行以下操作:
awk 'NF{ skip=0; printf $0; next} !skip{ printf RS; skip=1 } END{ print ""}' infile
答案4
使用 POSIXly sed 的一种方法是:
sed -e '
/./!d
$ba
N
/\n$/!{H;s/.*//;x;D;}
:a;s/\n//g
' input.txt
输入:
% cat -ne input.txt
1 $
2 $
3 john,$
4 5901,$
5 open$
6 $
7 $
8 $
9 lina,$
10 2401,$
11 open$
12 $
13 jody,$
14 5401,$
15 open$
输出:
john,5901,open
lina,2401,open
jody,5401,open
解释:
- 每当
sed
看到非空行(任何字符,甚至空白都可以)时,它就会开始将其附加到模式空间中并读取下一行。 - 现在,如果模式空间的最右边部分(意味着读入模式空间的当前行是空行或最后一行),那么我们分支到标签
:a
,立即从模式空间中删除换行符并打印到标准输出。 - 如果刚刚读取的行不是绝对空的,则在附加到模式空间后,
/\n$/
我们返回并附加下一行。我们通过将D
控制转移到代码顶部的命令来完成此操作sed
。但在此之前,它会清理模式空间中第一个换行符之前的所有内容。我们通过放置一个\n
byH;s/.*//;x
工件来管理。