在每第二个“,”之后分隔元素并推入 bash 中的下一行

在每第二个“,”之后分隔元素并推入 bash 中的下一行

我的文件的一个示例如下所示:

201012,720,201011,119,201710,16

我想要的输出:

201012,720
201011,119
201710,16

答案1

使用 Sed 循环:

sed -e 's/,/\n/2' -e 'P;D' file

前任。

$ echo '201012,720,201011,119,201710,16' | sed -e 's/,/\n/2' -e 'P;D'
201012,720
201011,119
201710,16

这会将第二个替换,\n,然后重复打印并删除\n, 直到替换不再成功。

BSD 不理解命令\n右侧的换行符s,这是 ksh、bash、zsh shell 的解决方法:

sed -e :a -e $'s/,/\\\n/2' -e 'P;D' file

或者,(旧)sed 的通用解决方案:

sed '
:a
s/,/\
/2
P;D
' file

答案2

$ paste -d, - - < <( tr ',' '\n' <file )
201012,720
201011,119
201710,16

或者,在没有过程替换的情况下,

$ tr ',' '\n' <file | paste -d, - -
201012,720
201011,119
201710,16

这将使用 替换文件中的所有逗号为换行符tr,然后使用paste创建由逗号分隔的两列。

如果tr感觉有点太简单了,你可以用 替换它sed 'y/,/\n/',它的作用是一样的。

答案3

我可以使用以下 awk 命令来完成此操作:

awk -F, -v OFS=, '{for (i=1;i<=NF;i=i+2) {j=i+1; print $i,$j}}' input

这将循环遍历输入中的每一列(每次迭代增加 2)并打印该列以及一行上的下一个相邻列,然后再移动到下一行。

$ cat input
201012,720,201011,119,201710,16
$ awk -F, -v OFS=, '{for (i=1;i<=NF;i=i+2) {j=i+1; print $i,$j}}' input
201012,720
201011,119
201710,16

答案4

使用xargsprintf

xargs -d, printf '%s,%s\n' < file

输出:

201012,720
201011,119
201710,16

上面的代码假设每行有偶数个字段。如果没有,xargs将打印单独的数字和悬空逗号。但是这个稍微慢一些的代码应该可以完成大多数事情:

tr , '\n' < file | xargs -n2 printf '%s,%s\n' | sed '$s/,$//'

-n2可以通过增加到某个合理的最大值来加速甚至数字,例如假设输入中的数字不超过 15 位:

m=$(getconf ARG_MAX) m=$(( (m/16) + (m%2) ))
tr , '\n' < file | xargs -n"${m}" printf '%s,%s\n' | sed '$s/,$//'

相关内容