如何将文件流分割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
在命令行中使用过,所以如果您有这样的命令,也可以在代码中将xargs
SOH 波浪线更改为实际的 START OF HEADING 。\001
awk
我们也可以设置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