一次又一次,一次又一次——又是无数次……
不要使用类似的结构
for file in `cat path.txt`
或者
for file in `find .....`
for file in `any command what produces filenames`
因为当文件名或路径包含空格时,代码会立即中断。永远不要将它用于任何产生文件名的命令。不好的做法。很坏。它是不正确的、错误的、错误的、不准确的、不精确的、不精确的、有缺陷的、错误的。
正确的形式是:
for file in some/* #if want/can use filenames directly from the filesystem
或者
find . -print0 | while IFS= read -r -d '' file
或(如果您确定没有文件名包含换行符)可以使用
cat path.txt | while read -r file
但这里cat
是没用的,(真的 -只将文件复制到 STDOUT的命令是没用的)。你应该改用
while read -r file
do
#whatever
done < path.txt
它更快(不会像每个管道那样分叉一个新进程)。
如果文件名也包含空格,上面while
的 s 会将正确的文件名填充到变量中。不会。file
_ 时期。呃。我的天啊。for
出于同样的原因,使用"$variable_with_filename"
而不是纯。$variable_with_filename
如果文件名包含空格,则任何命令都会将其误解为两个文件名。这可能不是,你也想要什么..
因此,将任何包含文件名的 shell 变量用双引号括起来。(不仅是文件名,还有任何可以包含空格的东西)。"$variable"
是正确的。
如果我理解正确,您希望将文件复制到返回错误/data/temp
时。gdalinfo
while read -r file
do
gdalinfo "$file" || cp "$file" /data/temp
done < path.txt
不错,简短且安全(至少如果您的 path.txt 确实每行包含一个文件名)。
也许,你想多次使用你的脚本,因此不要把里面的文件名拿出来,而是把脚本保存在一个表格中
while read -r file
do
gdalinfo "$file" || cp "$file" /data/temp
done
并像这样使用它:
mygdalinfo < path.txt
更通用...
也许,您只想显示gdalinfo
返回错误的文件名
while read -r file
do
gdalinfo "$file" || printf "$file\n"
done
如果您将其更改为printf "$file\n"
,printf "$file\0"
则可以安全地在管道中使用脚本,因此:
while read -r file
do
gdalinfo "$file" || printf "$file\0"
done
并将其用作例如:
mygdalinfo < path.txt | xargs -0 -J% mv % /tmp/somewhere
豪。