![在unix中动态合并多行](https://linux22.com/image/1566660/%E5%9C%A8unix%E4%B8%AD%E5%8A%A8%E6%80%81%E5%90%88%E5%B9%B6%E5%A4%9A%E8%A1%8C.png)
我有以下场景:
迭代 1 -
Ddd
Bbb
Ccc
Ddd
Eee
Fff
Ddd
迭代 2 -
Ddd
Bbb
Ddd
我想合并以下数据 -
迭代 1 输出 -
Ddd Bbb Ccc
Ddd Eee Fff
Ddd
迭代 2 输出 -
Ddd bbb
Ddd
我想使用 awk NR 创建动态块来组合数据,即迭代 1 输出中的 NR%3 和迭代 2 输出中的 NR%2。
我尝试使用变量动态分配值,即 NR%$cnt,但导致错误。
请协助。
答案1
我的方法不需要假设Ddd
发生的频率;它可以不定期发生。该方法应该有效,除非您的输入中某处有空字符,或者输入没有以换行符结尾(请参阅这),或者您的工具受到限制(例如sed -z
未由 POSIX 指定)。
sed '1! s/^Ddd$/\x00Ddd/' | tr '\n' ' ' | sed -z 's/ $/\n/' | tr -d '\0'
步骤:
sed
检测是否存在行,Ddd
并在每行前面添加一个空字符,除非该行是第一行。这些空字符现在将我们要划分的行分开。tr
将每个换行符替换为空格符。这将构建我们的行:以前的行现在用空格分隔。- 除最后一行外,每一行末尾都包含一个额外的空格,该空格来自 之前原本的换行符
Ddd
;最后一行包含一个额外的空格,该空格来自 POSIX 要求的最后一个换行符。sed -z
读取以空字符结尾的字符串(待行)并将这些尾随空格字符替换为普通换行符。此时待行变为常规行。 tr -d
删除空字符。
答案2
您也许可以使用它(它来自 GNU coreutils):
pr --columns=3 --across --separator=' ' --omit-pagination # pr -3 -a -s' ' -T
它会读取标准输入或来自文件。输入第一列数据,输出如下:
Ddd Bbb Ccc
Ddd Eee Fff
Ddd
--columns=3
将--columns=2
第二个文件更改为:
Ddd bbb
Ddd
答案3
这是一个选项(来自 GNU findutils):
xargs --no-run-if-empty --max-args=3 # xargs -r -n3
它会读取标准输入或来自文件。输入第一列数据,输出如下:
Ddd Bbb Ccc
Ddd Eee Fff
Ddd
--max-args=3
将--max-args=2
第二个文件更改为:
Ddd bbb
Ddd
这是另一个选项,这次基于awk
。将第二个文件更改为NR % 3
。NR % 2
awk '{ printf "%s", $0 } { if (NR % 3) { printf " " } else { printf "\n" } }'