我已经看到了一些与此相关的答案,但作为一个新手,我真的不明白如何在我的脚本中实现它。
这应该很容易(对于那些可以做这样的事情的人)
我正在使用一个简单的
for f in "/drive1/"images*.{jpg,png}; do
但这只是超载并给了我
Argument list too long
这个最简单的问题如何解决?
参数列表长度受您的配置限制。
getconf ARG_MAX
2097152
但是在讨论了 bash 细节和系统(操作系统)限制之间的差异之后(请参阅其他人的评论),这个问题似乎是错误的:
关于评论的讨论,OP尝试了类似的东西:
ls "/simple path"/image*.{jpg,png} | wc -l
bash: /bin/ls: Argument list too long
发生这种情况是因为操作系统限制,而不是bash!!
但是用OP代码进行测试,效果很好
for file in ./"simple path"/image*.{jpg,png} ;do echo -n a;done | wc -c
70980
喜欢:
printf "%c" ./"simple path"/image*.{jpg,png} | wc -c
第一步:你可以通过以下方式减少参数长度:
cd "/drive1/"
ls images*.{jpg,png} | wc -l
但是当文件数量增加时,你又会遇到问题...
find "/drive1/" -type f \( -name '*.jpg' -o -name '*.png' \) -exec myscript {} +
如果您希望这不是递归的,您可以添加
-maxdepth
作为第一个选项:
find "/drive1/" -maxdepth 1 -type f \( -name '*.jpg' -o -name '*.png' \) \
-exec myscript {} +
在那里,
myscript
将以文件名作为参数运行。 myscript
的命令行会建立起来,直到达到系统定义的限制。
myscript /drive1/file1.jpg '/drive1/File Name2.png' /drive1/...
来自
man find
:
-exec command {} + This variant of the -exec action runs the specified command on the selected files, but the command line is built by appending each selected file name at the end; the total number of invoca‐ tions of the command will be much less than the number of matched files. The command line is built in much the same way that xargs builds its command lines. Only one instance of `{}'
您可以像这样创建脚本
#!/bin/bash
target=( "/drive1" "/Drive 2/Pictures" )
[[ $1 == --run ]] &&
exec find "${target[@]}" -type f \( -name '*.jpg' -o -name '*.png' \) \
-exec $0 {} +
for file ;do
echo Process "$file"
done
然后你必须使用
--run
作为参数来运行它。
可处理任意数量的文件! (递归!请参阅
maxdepth
选项)
允许很多
target
允许在文件和目录名称中使用空格和特殊字符
您可以直接在文件上运行相同的脚本,无需
--run
:
./myscript hello world 'hello world'
Process hello
Process world
Process hello world
使用数组,您可以执行以下操作:
allfiles=( "/drive 1"/images*.{jpg,png} )
[ -f "$allfiles" ] || { echo No file found.; exit ;}
echo Number of files: ${#allfiles[@]}
for file in "${allfiles[@]}";do
echo Process "$file"
done
还有一个 while 读取循环:
find "/drive1/" -maxdepth 1 -mindepth 1 -type f \( -name '*.jpg' -o -name '*.png' \) |
while IFS= read -r file; do
或以零结尾的文件:
find "/drive1/" -maxdepth 1 -mindepth 1 -type f \( -name '*.jpg' -o -name '*.png' \) -print0 |
while IFS= read -r -d '' file; do