使行到第 n 列在最后一行插入换行符

使行到第 n 列在最后一行插入换行符

我有文件.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。但在此之前,它会清理模式空间中第一个换行符之前的所有内容。我们通过放置一个\nbyH;s/.*//;x工件来管理。

相关内容