我目前最好的选择是:
for i in $(find . -name *.jpg); do echo $i; done
问题:不处理文件名中的空格。
注意:我也希望采用图形方式来执行此操作,例如“ tree”命令。
我目前最好的选择是:
for i in $(find . -name *.jpg); do echo $i; done
问题:不处理文件名中的空格。
注意:我也希望采用图形方式来执行此操作,例如“ tree”命令。
Answers:
规范的做法是
find . -name '*.jpg' -exec echo {} \;
(替换\;
与+
一个以上的文件传递给echo
在时间)
或(特定于GNU,尽管某些BSD现在也有它):
find . -name '*.jpg' -print0 | xargs -r0 echo
zsh:
for i (**/*.jpg(D)) echo $i
echo
扩展转义序列,例如\b
(至少是Unix兼容echo
的)。
find
手册页显示find . -type f -exec file '{}' \;
的EXAMPLES
部分。也许有些贝壳会专门处理牙套。
'{}'
,\{\}
,{}
,"{}"
,'{'}
由外壳(任何类似Bourne外壳)扩展到一个参数,发现是两个字符“{”和“}”。将“查找”替换为“回声查找”,或者printf '<%s>\n' find
如果您要仔细检查,则将其替换。
已经给出了更好的答案。
但是请注意,空格并不是您提供的代码中的唯一问题。标签,换行符和通配符也是一个问题。
用
IFS='
'
set -f
for i in $(find . -name '*.jpg'); do echo "$i"; done
那么只有换行符是一个问题。
您所提到的是人们尝试读取文件名时面临的基本问题之一。有时,知识有限且对文件和文件夹结构有误解的人往往会忘记“ 在UNIX中,一切都是文件 ”。因此,他们不知道他们也需要处理空格,因为文件名可以包含2个或更多带空格的单词。
解决方案:因此,执行此操作的最知名方法之一是进行完整读取。
我们将在这里读取存在的所有文件并将它们保存在变量中,下一次在进行所需的处理时,我们只需要将该变量保留在引号内即可将文件名保留空格。这是执行此操作的基本方法之一,但是其他人在此处提供的其他答案也同样有效。
脚本:
find /path/to/files/ -iname "*jpg" | \
while read I; do
cp -v --parent "$I" /backup/dir/
done
在这里,我通过给它们提供路径来读取文件,无论读取什么,我都将它们保存在变量I中,稍后我将在处理该文件时引用该变量以保留空间以便正确处理它。
希望这对您有所帮助。
只需使用find
和bash
:
find . -name '*.jpg' -exec bash -c '
echo "treating file $1 in bash, from path : ${1%/*}"
' -- {} \;
这样,我们$1
在bash中使用,就像在基本脚本中一样,使用bash打开漂亮的视角来执行任何高级(或不执行)任务。
一种更有效的方法(避免必须为每个文件启动新的bash):
find . -name '*.jpg' -exec bash -c 'for i do
echo "treating file $i in bash, from path : ${i%/*}"
done' -- {} +
在最新版本的bash中,可以使用以下globstar
选项:
shopt -s globstar
for file in **/*.jpg ; do
echo "$file"
done
对于简单的操作,您甚至可以完全跳过循环:
echo **/*.jpg
set -G
)中有效,但不应将其用于bash中,因为bash版本从根本上被破坏(就像GNU一样grep -r
),因为它会下降到目录的符号链接中(等效于find -L
zsh或***/*.jpg
)。另请注意,与find相反,它将忽略点文件,而不会下降到dotdirs(默认情况下)。
$i
吗?我做到了,效果很好。这种方法有什么问题吗?