我想在while循环中处理来自管道的数据。但是,数据由3个正斜杠字符而不是换行符分隔,因为我希望脚本能够处理包含换行符的输入。
# The normal `read`-driven while loop
while read -r; do
echo "$REPLY"
done
我想用sed
代替read
,因为它允许更灵活的读取输入。我遇到的问题是,sed
在第一次通过while循环从管道中吃掉所有数据,所以循环只运行一次。
我是这样测试的
(注1:使用fd
,一个文件查找工具)
# Make some files
mkdir test-{1,2}
touch 'test-1/file' $'test-2/filenwith a newline'
# Find the files we just created
# note 2: there are some wide comments here ->>>
fd -t f . test-1/ test-2/ -Hx printf '%s///' '{}' | # List all files in test-1 and test-2, putting "///" at the end of each one
sed 's/./n&/g' | # prepend each character with a newline so it can be read by `sed` one character at a time
while v="$(sed -n ':loop; N; s|n(.)$|1|; ////$/!{b loop}; s|///$||; p;Q;')"; do
# ^^^^^^ sed script that prints everything up to the "///"
# that notates the end of the current path, then exits
# without processing more than the first one (so the
# rest can be processed in future loop iterations)
if [ -n "$v" ]; then
# print the file name
echo "$v"
else
# if v is empty
break
fi
done
这个的输出是
test-1/file
…表示sed
只运行一次,因为输出应该是这样的:
test-1/file
test-2/file
with a newline
有没有办法让sed
表现得像read
,所以它可以在while
循环中使用?是否有一个神奇的属性,允许read
这样做,因为它是一个内置的?
我猜你是在问XY问题。
我希望脚本能够处理其中有换行符的输入。
使用零分隔流。
# I would do standard: find . -type f -print0 |
fd -H0t f . |
while IFS= read -r file; do
echo "$line"
done
要处理以3个斜杠分隔的流,您将用0字节替换3个斜杠,然后读取以0分隔的流。如果你的流中有实际的零字节,这可能是一个问题,但这是在文件名不可能的情况下。
... |
sed 's|///|x00|g' |
while IFS= read -r file; do