脚本中的规避参数列表太长(for 循环)
Circumvent Argument list too long in script (for loop)
我已经看到了一些关于这个的答案,但作为一个新手,我真的不明白如何在我的脚本中实现它。
这应该很容易(对于那些有能力的人来说)
我使用的是简单的
for f in "/drive1/"images*.{jpg,png}; do
但这只是超载并给我
Argument list too long
这个最简单的解决方法是什么?
参数列表太长 解决方法
参数列表长度受您的配置限制。
getconf ARG_MAX
2097152
但在讨论 bash specifics and system (os) limitations (see ) 之间的差异之后,这个问题似乎是错误的:
关于评论讨论,OP 尝试了类似的方法:
ls "/simple path"/image*.{jpg,png} | wc -l
bash: /bin/ls: Argument list too long
发生这种情况是因为 OS 限制,而不是 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" )
[ "" = "--run" ] && exec find "${target[@]}" -type f \( -name '*.jpg' -o \
-name '*.png' \) -exec [=19=] {} +
for file ;do
echo Process "$file"
done
然后你必须 运行 以 --run
作为参数。
处理 任意 个文件! (递归!参见 maxdepth
选项)
允许多个target
允许在文件和目录名称中使用 空格 和 特殊字符
您可以 运行 直接在文件上使用相同的脚本,而不需要 --run
:
./myscript hello world 'hello world'
Process hello
Process world
Process hello world
使用纯bash
使用数组,您可以执行以下操作:
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 read 循环:
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
我已经看到了一些关于这个的答案,但作为一个新手,我真的不明白如何在我的脚本中实现它。
这应该很容易(对于那些有能力的人来说)
我使用的是简单的
for f in "/drive1/"images*.{jpg,png}; do
但这只是超载并给我
Argument list too long
这个最简单的解决方法是什么?
参数列表太长 解决方法
参数列表长度受您的配置限制。
getconf ARG_MAX
2097152
但在讨论 bash specifics and system (os) limitations (see
关于评论讨论,OP 尝试了类似的方法:
ls "/simple path"/image*.{jpg,png} | wc -l
bash: /bin/ls: Argument list too long
发生这种情况是因为 OS 限制,而不是 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" )
[ "" = "--run" ] && exec find "${target[@]}" -type f \( -name '*.jpg' -o \
-name '*.png' \) -exec [=19=] {} +
for file ;do
echo Process "$file"
done
然后你必须 运行 以 --run
作为参数。
处理 任意 个文件! (递归!参见
maxdepth
选项)允许多个
target
允许在文件和目录名称中使用 空格 和 特殊字符
您可以 运行 直接在文件上使用相同的脚本,而不需要
--run
:./myscript hello world 'hello world' Process hello Process world Process hello world
使用纯bash
使用数组,您可以执行以下操作:
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 read 循环:
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