我正在尝试运行一个简单的 bash 脚本,但我正在为如何整合一个条件而苦苦挣扎。任何指针。循环说。我想加入一个条件,这样当 gdalinfo 无法打开图像时,它会将特定文件复制到另一个位置。
for file in `cat path.txt`; do gdalinfo $file;done
在打开图片时效果很好,还显示了哪些图片无法打开。
错误代码是
for file in `cat path.txt`; do gdalinfo $file && echo $file; else cp $file /data/temp
最佳答案
一次又一次 - 无数次......
不要使用像
这样的结构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
速度更快(不会像 every 管道那样 fork 新进程)。
在文件名也包含空格的情况下,上面的while
s 会将正确的文件名填充到变量file
中。 for
不会。时期。呃。天哪。
出于同样的原因,使用 "$variable_with_filename"
而不是纯粹的 $variable_with_filename
。如果文件名包含空格,任何命令都会将其误解为两个文件名。这可能不是,你也想要什么..
因此,用双引号将包含文件名的任何 shell 变量括起来。 (不仅是文件名,还有任何可以包含空格的内容)。 "$variable"
是正确的。
如果我理解正确,当 gdalinfo
返回错误时,您希望将文件复制到 /data/temp
。
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
吼。
关于bash 脚本和条件语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17744562/