使用awk

使用awk

我有一种方法可以将单行拆分为 3 列的多行。文件中所有行的末尾缺少新行字符。

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

awk '{ gsub(",", "\n") } 6' filename

其中filename的内容如下所示:

A,B,C,D,E,F,G,H,I,J,K,L,M,N,O

所需的输出每行有 3 列:

A,B,C
D,E,F
G,H,I
J,K,L
M,N,O

答案1

使用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

怎么运行的

  • -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

怎么运行的

  • 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

怎么运行的

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

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

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

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

答案2

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

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

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

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

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

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

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

  6. g意味着对线路上的所有实例执行此操作。

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

相关内容