我的目录包含以下文件:
FILE1_h0_something_1950_other.gz
FILE2_h0_something_1950_other.gz
FILE3_h0_something_1950_other.gz
Run Code Online (Sandbox Code Playgroud)
这是我的bash脚本的一部分:
year=1950
for nc_gz in "$input_path/*h3*$year*.gz"; do
gunzip $nc_gz
done
Run Code Online (Sandbox Code Playgroud)
我注意到有些时候(奇怪的行为……我总是或永远没有,除非如此)在我的目录中创建了一个名为* h3 * 1950 *的文件。
当目录不包含gz文件时,代码将失败。
问题出在哪里?
谢谢
Run Code Online (Sandbox Code Playgroud)for nc_gz in "$input_path/*h3*$year*.gz"; do
您正在遍历一个元素的列表。由于"$input_path/*h3*$year*.gz"用双引号引起来,所以它是一个字符串。因此,如果input_pathis 的值和is /some/where的值,year则会2017运行一次循环主体,并将其nc_gz设置为/some/where/*h3*2017*.gz。
Run Code Online (Sandbox Code Playgroud)gunzip $nc_gz
这里$nc_gz未引用,因此将split + glob运算符应用于结果。在上面的示例中,/some/where/*h3*2017*.gz将展开为匹配文件列表;除非没有匹配的文件,否则将gunzip使用参数调用/some/where/*h3*2017*.gz。
首先,正确引用:
对于“ $ input_path / ” * h3 * “ $ year ” * .gz中的nc_gz ; 做
gunzip “ $ nc_gz ”
做完了
如果通配符不匹配任何文件,这仍然会运行一次循环,这是因为外壳功能不匹配的通配符模式保留不变,而不是扩展为空列表。在bash中(但不是普通sh),可以通过设置nullglob选项来避免这种情况。
#!/bin/bash
shopt -o nullglob
for nc_gz in "$input_path/"*h3*"$year"*.gz; do
gunzip "$nc_gz"
done
Run Code Online (Sandbox Code Playgroud)
简而言之,您可以通过跳过不存在的文件来避免这种情况。
for nc_gz in "$input_path/"*h3*"$year"*.gz; do
if [ ! -e "$nc_gz" ]; then continue; fi
gunzip "$nc_gz"
done
Run Code Online (Sandbox Code Playgroud)
请注意,我以为这是简化的代码,您确实需要循环来执行除调用之外的其他事情gunzip。如果您需要做的只是解压缩文件,则可以调用gunzip一次,因为它支持多个文件参数。
gunzip "$input_path/"*h3*"$year"*.gz
Run Code Online (Sandbox Code Playgroud)
这在解压缩文件的意义上起作用,并且如果通配符模式与任何文件都不匹配,则不会执行任何操作,但是gunzip会抱怨不存在的文件。bash的nullglob选项对您没有帮助,因为gunzip没有文件名的调用也不起作用(它希望从其标准输入中解压缩数据)。您需要测试匹配文件的数量。
unzip_matching_files () {
if [ $# -eq 1 ] && [ ! -e "$1" ]; then return; fi
gunzip "$@"
}
unzip_matching_files "$input_path/"*h3*"$year"*.gz
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1233 次 |
| 最近记录: |