我有一种方法可以将单行拆分为 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 在输出中使用逗号作为字段分隔符。
使用tr
和paste
$ 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 答案。
该解决方案使用 GNU sed 的扩展正则表达式功能。
\(..\)
是一个正则表达式集合组。请注意,该解决方案使用两个,一个嵌套在另一个中。[^,]+,
是任何不带逗号且后跟逗号的字符串。在您的情况下,是一列或字段。\{3\}
是一个正则表达式乘数,表示使用之前的正则表达式三次。\1
是正则表达式反向引用。到之前的正则表达式。g
意味着对线路上的所有实例执行此操作。s/,\n/\n/g
删除结尾的逗号。这里有必要包含换行符,因为sed
仍然将输入视为单行。