将单行拆分为多行,输入文件中的所有行都缺少换行符

Rak*_*h K 6 linux text-processing split newlines

我有一种方法可以将单行分成 3 列的多行。文件中所有行的末尾都缺少换行符。

我尝试使用 awk,但它将每列拆分为一行,而不是每行中的 3 列。

awk '{ gsub(",", "\n") } 6' filename
Run Code Online (Sandbox Code Playgroud)

wherefilename的内容如下所示:

A,B,C,D,E,F,G,H,I,J,K,L,M,N,O
Run Code Online (Sandbox Code Playgroud)

所需的输出每行有 3 列:

A,B,C
D,E,F
G,H,I
J,K,L
M,N,O
Run Code Online (Sandbox Code Playgroud)

Joh*_*024 11

使用 awk

$ awk -v RS='[,\n]' '{a=$0;getline b; getline c; print a,b,c}' OFS=, filename
A,B,C
D,E,F
G,H,I
J,K,L
M,N,O
Run Code Online (Sandbox Code Playgroud)

这个怎么运作

  • -v RS='[,\n]'

    这告诉 awk 使用任何出现的逗号或换行符作为记录分隔符。

  • a=$0; getline b; getline c

    这告诉 awk 将当前行保存在变量中a,下一行保存在变量中,下一行保存b在变量中c

  • print a,b,c

    这告诉 awk 打印a, b, 和c

  • OFS=,

    这告诉 awk 在输出时使用逗号作为字段分隔符。

使用trpaste

$ tr , '\n' <filename | paste -d, - - -
A,B,C
D,E,F
G,H,I
J,K,L
M,N,O
Run Code Online (Sandbox Code Playgroud)

这个怎么运作

  • tr , '\n' <filename

    这将从文件名中读取,同时将所有逗号转换为换行符。

  • paste -d, - - -

    paste是从标准输入中读取三行(每行一行-)并将它们粘贴在一起,每行用逗号 ( -d,)分隔。

替代awk

$ awk -v RS='[,\n]' '{printf "%s%s",$0,(NR%3?",":"\n")}' filename
A,B,C
D,E,F
G,H,I
J,K,L
M,N,O
Run Code Online (Sandbox Code Playgroud)

这个怎么运作

  • -v RS='[,\n]'

    这告诉 awk 使用任何出现的逗号或换行符作为记录分隔符。

  • printf "%s%s",$0,(NR%3?",":"\n")

    这告诉 awk 打印当前行,后跟逗号或换行符,具体取决于当前行号的值NR,模 3。


use*_*316 5

sed 's/\(\([^,]\+,\)\{3\}\)/\1\n/g;s/,\n/\n/g' filename
Run Code Online (Sandbox Code Playgroud)

我知道您要求提供一个awk解决方案,我现在尝试将其提交为对此答案的编辑,但对我而言,sed解决方案更简单......并且用户 john1024 击败了我,提供了一个很好的awk解决方案. 看那里。他pastetr解决方案可能是最合适的经典UNIX十岁上下的答案。

  1. 此解决方案使用 GNU sed 的扩展正则表达式功能。

  2. \(..\)是一个正则表达式集合组。请注意,该解决方案使用两个,一个嵌套在另一个中。

  3. [^,]+,是任何没有逗号后跟逗号的字符串。在您的情况下,是列或字段。

  4. \{3\} 是正则表达式乘数,表示使用先前的正则表达式三次。

  5. \1是一个正则表达式反向引用。到先前的正则表达式。

  6. g 意味着对线上的所有实例都这样做。

  7. s/,\n/\n/g删除尾随逗号。这里有必要包含换行符,因为sed仍然将输入视为单行。