bash脚本和条件语句

kar*_*eek 2 bash

我正在尝试运行一个简单的bash脚本,但我正在努力解决如何陷入困境.任何指针.循环说.我想加入一个条件,当gdalinfo无法打开图像时,它会将该特定文件复制到另一个位置.

for file in `cat path.txt`; do gdalinfo $file;done
Run Code Online (Sandbox Code Playgroud)

在打开图像时工作正常,还可以显示哪些图像无法打开.
错误的代码是

for file in `cat path.txt`; do gdalinfo $file && echo $file; else cp $file /data/temp
Run Code Online (Sandbox Code Playgroud)

jm6*_*666 6

再次,一次又一次 - zilion再次......

不要使用类似的结论

for file in `cat path.txt`
Run Code Online (Sandbox Code Playgroud)

要么

for file in `find .....`
for file in `any command what produces filenames`
Run Code Online (Sandbox Code Playgroud)

因为当文件名或路径包含空格时,代码将立即BREAK.永远不要将它用于任何产生文件名的命令.不好的做法.很坏.它是错误的,错误的,错误的,不准确的,不精确的,不精确的,错误的,错误的.

正确的形式是:

for file in some/*   #if want/can use filenames directly from the filesystem
Run Code Online (Sandbox Code Playgroud)

要么

find . -print0 | while IFS= read -r -d '' file
Run Code Online (Sandbox Code Playgroud)

或者(如果你确定没有文件名包含换行符)可以使用

cat path.txt | while read -r file
Run Code Online (Sandbox Code Playgroud)

但这里cat没用,(真的 - 命令将文件复制到STDOUT 没用的).你应该使用

while read -r file
do
   #whatever
done < path.txt
Run Code Online (Sandbox Code Playgroud)

它更快(不会分叉新进程,就像每个管道一样).

在文件名也包含空格的情况下,上面的whiles会将corect文件名填充到变量file中.该for 不会.期.UFF.我的天啊.

并出于同样的原因使用"$variable_with_filename"而不是纯粹$variable_with_filename的.如果文件名包含空格,则任何命令都会将其误解为两个文件名.这可能不是,你想要的......

因此,请包含任何包含带双引号的文件名的shell变量.(不仅是文件名,还包含任何可以包含空格的东西)."$variable"是正确的.

如果我理解正确,你想要/data/tempgdalinfo返回错误时复制文件.

while read -r file
do
   gdalinfo "$file" || cp "$file" /data/temp
done < path.txt
Run Code Online (Sandbox Code Playgroud)

不错,简短且安全(至少如果你的path.txt每行真的包含一个文件名).

也许,你想要更多次使用你的脚本,因此不要在里面输出文件名,而是将脚本保存在表单中

while read -r file
do
   gdalinfo "$file" || cp "$file" /data/temp
done
Run Code Online (Sandbox Code Playgroud)

并使用它像:

mygdalinfo < path.txt
Run Code Online (Sandbox Code Playgroud)

更普遍......

也许,你只想显示gdalinfo返回错误的文件名

while read -r file
do
   gdalinfo "$file" || printf "$file\n"
done
Run Code Online (Sandbox Code Playgroud)

如果更改为printf "$file\n",则printf "$file\0"可以安全地在管道中使用脚本,因此:

while read -r file
do
   gdalinfo "$file" || printf "$file\0"
done
Run Code Online (Sandbox Code Playgroud)

并将其用作例如:

 mygdalinfo < path.txt | xargs -0 -J% mv % /tmp/somewhere
Run Code Online (Sandbox Code Playgroud)

Howgh.