处理文本流部分,用 ␁ 分隔

处理文本流部分,用 ␁ 分隔

如何将文件流分割stdin成更小的部分,每个部分都传递给脚本,

我有一个大文件,类似于stdin...

␁HeadingHere
abcd
abcd
␁Different Title
bcde
bcde
{a lot longer}
␁Different again!
cdef
cdef   

我正在寻找一种将这些部分传递给./script.sh

这将模拟做:

cat <<EOF | ./script.sh
␁HeadingHere
abcd
abcd
EOF

cat <<EOF | ./script.sh
␁Different Title 
bcde
bcde
{a lot longer}
EOF

cat <<EOF | ./script.sh
␁Different again!
cdef
cdef
EOF

每个部分都可以通过将它们分开来确定

我想过使用xargs并做一些类似的事情 xargs -d '\01' -n1 echo,但遇到了xargs: argument line too long

理想情况下,脚本将posix兼容

答案1

您可以将这些部分拆分为单独的文件并逐一处理它们。这会产生outfile.1等:

awk '/^␁/ { count++ } { print > "outfile." count }  ' < file

或者,您可以将awk这些部分逐一通过管道传递给命令:

awk  'BEGIN {command = "./script.sh"} /^␁/ { close(command) }
      { print | command } ' < file

我在上面使用了文字 U+2401 符号作为标题的开始,因为这就是复制粘贴给我的。您\01在命令行中使用过,所以如果您有这样的命令,也可以在代码中将xargsSOH 波浪线更改为实际的 START OF HEADING 。\001awk


我们也可以设置RS为 SOH,但这并不完全合适,因为这里我们在记录的开头有 SOH,并且awk期望在末尾找到记录分隔符。

答案2

如果源文件没有空行(两个连续的换行符),则可以使用 sed 将每个空行转换为两个换行符。这将创建一个文件(或流),其中有一个空行作为每个记录的分隔符。然后,awk(带有空 RS)能够将每个“空行”分隔文件(流)分隔成“记录”。

描述听起来可能很复杂,但看一下代码:

sed 's/␁/\n\n/g' file | awk -v RS='' -vf="./script" '{print|f;close(f)}'

如果您确实需要转换字节值为 0x01 的字符,请在 sed 命令中替换为。\x01

相关内容