如何在bash脚本中处理find的结果?

She*_*ner 61 bash find

我正在尝试使用数组来使用该find命令存储文件名列表.

由于某些原因,该阵列无法在学校使用的bash中工作,我的程序在我自己的笔记本电脑上工作.

所以我想知道是否有另一种方法可以做到这一点,这就是我所拥有的:

array = (`find . -name "*.txt"`)  #this will store all the .txt files into the array
Run Code Online (Sandbox Code Playgroud)

然后我可以使用cat命令访问数组项并复制所有文件.

有没有其他方法可以不使用数组?

Joh*_*iss 115

你可以使用这样的东西:

find . -name '*.txt' | while read line; do
    echo "Processing file '$line'"
done
Run Code Online (Sandbox Code Playgroud)

例如复制:

find . -name '*.txt' | while read line; do
    echo "Copying '$line' to /tmp"
    cp -- "$line" /tmp
done
Run Code Online (Sandbox Code Playgroud)

HTH

  • 请注意:这个“while”在子 shell 中运行,因为它是管道中的第二个命令,因此在该循环中所做的更改在循环退出后不可用。我无法将其附加到循环外部声明的变量。从这里:/sf/ask/1588400551/ (3认同)
  • 使用**find**和'for'或'while'主要是一个坏主意.您将文件名作为字符串传递并获得空白和屏蔽的所有问题,而将unmasked {}与finds -exec,-execdir,-ok,-okdir一起使用是没有问题的.试试`a b.txt`. (2认同)
  • 如果您希望循环产生副作用,那么我会非常谨慎地使用construct。例如`a = 1; 序列3 | 边读边;做a = 2; 完成 echo $ a`打印`1` (2认同)

sta*_*use 22

我对JohannesWeiß的解决方案有疑问,如果我只是做一个回声,它将适用于完整的文件列表.但是,如果我尝试在下一行运行ffmpeg,脚本将只处理它遇到的第一个文件.我假设有一些IFS有趣的业务,因为管道,但我无法搞清楚,并用一个for循环运行:

for i in $(find . -name '*.mov' ); 
do
    echo "$i"
done
Run Code Online (Sandbox Code Playgroud)

  • 对于文件名中的空格,这会失败 (5认同)

use*_*own 8

只是不要在等号周围放置空格:

ar=($(find . -name "*.txt"))
Run Code Online (Sandbox Code Playgroud)

如果可能的话,避免反引号,因为它们已被弃用.它们很容易与叛逆者混淆,特别是在字体不好的情况下,并且它们不能很好地嵌套.

在大多数情况下,如果您直接使用-exec,-execdir,-ok或-okdir迭代查找结果,那么您将获得最佳服务.

For和while循环在文件名或换行符和制表符中的空白时很难做到.

find ./ -name "*.txt" -exec grep {} ";"
Run Code Online (Sandbox Code Playgroud)

{}不需要屏蔽.您经常会看到一个组合find/xargs,它也会启动一个额外的过程:

find ./ -name "*.txt" | xargs grep {} ";"
Run Code Online (Sandbox Code Playgroud)


ber*_*uic 6

我认为starpause具有最干净的解决方案,但是当路径中存在空格时,它将失败。可以通过设置来固定IFS。因此正确的答案是:

IFS=$'\n'
for i in $(find . -name '*.mov' ); 
do
    echo "$i"
done
unset IFS
Run Code Online (Sandbox Code Playgroud)

您可以取消设置IFS以便重置IFS的行为以及为什么$需要使用IFS IFS=$'\n',请参见https://unix.stackexchange.com/questions/184863/what-is-the-意义-of-ifs-n-in- bash脚本