Ran*_*Rag 63 shell bash pipe find
我正在尝试使用 .bash 文件读取 bash 中命令的输出while loop
。
while read -r line
do
echo "$line"
done <<< $(find . -type f)
Run Code Online (Sandbox Code Playgroud)
我得到的输出
ranveer@ranveer:~/tmp$ bash test.sh
./test.py ./test1.py ./out1 ./test.sh ./out ./out2 ./hello
ranveer@ranveer:~/tmp$
Run Code Online (Sandbox Code Playgroud)
在这之后我试过了
$(find . -type f) |
while read -r line
do
echo "$line"
done
Run Code Online (Sandbox Code Playgroud)
但它产生了一个错误test.sh: line 5: ./test.py: Permission denied
。
那么,我如何逐行阅读它,因为我认为目前它正在一次吞食整行。
所需输出:
./test.py
./test1.py
./out1
./test.sh
./out
./out2
./hello
Run Code Online (Sandbox Code Playgroud)
Sté*_*las 14
请注意,没有什么可以阻止文件名包含换行符。为每个文件运行一个命令的正规途径发现的发现是。
find . -type f -exec cmd {} \;
Run Code Online (Sandbox Code Playgroud)
如果你想在 bash 中完成事情:
find . -type f -exec bash -c '
for file do
something with "$file"
done' bash {} +
Run Code Online (Sandbox Code Playgroud)
此外,在脚本中调用“读取”命令的规范方法(如果您不希望它对输入进行额外处理)是:
IFS= read -r var
Run Code Online (Sandbox Code Playgroud)
-r
是停止read
特殊处理反斜杠字符(作为分隔符和换行符的转义字符),并且 IFS= 将分隔符列表设置为空字符串read
(否则,如果该列表中有任何空白字符,它们将从输入的开始和结束)。
在 shell 中使用循环通常是一个坏主意(而不是在 shell 中如何让多个工具共同并发地工作,而不是按顺序运行一个或多个工具数百次)。
ᄂ ᄀ*_*ᄂ ᄀ 12
如果您想使用管道,则无需命令替换。默认情况下read
从读取stdin
,所以你只需管道进入它:
find . -type f -print0 |
while read -r -d '' line
do
echo "$line"
done
Run Code Online (Sandbox Code Playgroud)
或在一行
find . -type f -print0 | while read -r -d '' line; do echo "$line"; done
Run Code Online (Sandbox Code Playgroud)
使用-print0
和-d ''
是针对文件名中潜在换行符的保护措施,默认情况下表示行尾为read
(可以使用 更改-d
)。''
上面使用的实际上是空字节 in bash
(相当于$'\0'
)。
另一个已经提到的方法是使用find
's-exec
选项。这很可能是性能方面的最佳选择(记住使用-exec cmd {} +
变体,这样它就不会为正在处理的每一行分叉一个进程)。但这实际上取决于您在while
循环中执行的操作以及处理的数据量。对于您的情况,差异可能可以忽略不计或可以接受。