我的目录包含以下文件:
FILE1_h0_something_1950_other.gz
FILE2_h0_something_1950_other.gz
FILE3_h0_something_1950_other.gz
这是我的bash脚本的一部分:
year=1950
for nc_gz in "$input_path/*h3*$year*.gz"; do
gunzip $nc_gz
done
我注意到在我的目录中创建了一个名为 * h3 * 1950 * 的文件,有些奇怪的行为(我总是或从不这样做)。
当目录中不包含gz文件时代码失败。
问题出在哪里?
由于
答案 0 :(得分:4)
for nc_gz in "$input_path/*h3*$year*.gz"; do
您正在迭代一个元素的列表。由于"$input_path/*h3*$year*.gz"
是双引号,因此它是一个字符串。因此,如果input_path
的值为/some/where
且year
的值为2017
,那么这将运行循环体一次,nc_gz
设置为{{1} }}
/some/where/*h3*2017*.gz
此处 gunzip $nc_gz
未加引号,因此这会将split+glob operator应用于结果。在上面的示例中,$nc_gz
扩展为匹配文件列表;除非没有匹配的文件,否则会使用参数/some/where/*h3*2017*.gz
调用gunzip
。
首先,正确引用:
for nc_gz in "$input_path/"*h3*"$year"*.gz; do gunzip "$nc_gz" done
如果通配符与任何文件都不匹配,这仍然会运行一次循环,因为shell不匹配不匹配的通配符模式保持不变而不是扩展为空列表。在bash中(但不是简单的sh),您可以通过设置/some/where/*h3*2017*.gz
选项来避免这种情况。
nullglob
简单来说,你可以通过跳过不存在的文件来避免这种情况。
#!/bin/bash
shopt -o nullglob
for nc_gz in "$input_path/"*h3*"$year"*.gz; do
gunzip "$nc_gz"
done
请注意,我认为这是简化代码,除了调用for nc_gz in "$input_path/"*h3*"$year"*.gz; do
if [ ! -e "$nc_gz" ]; then continue; fi
gunzip "$nc_gz"
done
之外,您还需要循环来执行其他操作。如果您只需要解压缩文件,那么您可以一次调用gunzip
,因为它支持多个文件参数。
gunzip
这在解压缩文件的意义上是有效的,如果通配符模式与任何文件都不匹配,它就什么都不做,但是gunzip会抱怨不存在的文件。 bash的gunzip "$input_path/"*h3*"$year"*.gz
选项无法帮助您,因为在没有文件名的情况下调用nullglob
也不起作用(它希望从标准输入中解压缩数据)。您需要测试匹配文件的数量。
gunzip
答案 1 :(得分:0)
也许是这样吗?
for i in $(find ../path1 path2 path3 -name "*.env" 2>/dev/null); do
echo $i
done
忽略2> / dev / null的错误,否则将打印path1不存在
find: ‘../path1’: No such file or directory