如何在循环中访问文件名的结尾(扩展名之前)

如何在循环中访问文件名的结尾(扩展名之前)

我有一个文件名以 结尾的文件夹.TIF,我做了一个 for 循环

for i in *.TIF

在循环中,我想获取两种类型的文件结尾,例如(B4.TIF 和 B5.TIF)。

我这样做了,但是,它没有获取文件名的最后四个字母,而是将它们添加到末尾。

do ...... ${i}_B4.TIF -B ${i}_B5.TIF

我想要的结果是获取这些文件名以便进行一些计算

这些是文件夹中文件的示例

LC08_L1TP_195020_20170224_20170301_01_T1_B4.TIF  
LC08_L1TP_195020_20171107_20171121_01_T1_B4.TIF

LC08_L1TP_195020_20170224_20170301_01_T1_B5.TIF  
LC08_L1TP_195020_20171107_20171121_01_T1_B5.TIF

这是我用来进行计算的脚本

for i in *.TIF   
do 
    gdal_calc.py -A ${i}_B4_SA.TIF -B ${i}_B5_SA.TIF --type=Float32
--outfile=~/Geodata/goteborg/croped/ndvi/${i}_NDVI.TIF --calc="(B-A)/(B+A)"

done

最终输出将减去 B4 和 B5。所以这${i}_B4_SA.TIF -B ${i}_B5_SA.TIF应该得到两个文件名,如下所示:

LC08_L1TP_195020_20170224_20170301_01_T1_B4.TIF - 
LC08_L1TP_195020_20170224_20170301_01_T1_B5.TIF

答案1

循环构成一半对的文件,并为每个这样的文件构造相应对和输出文件的文件名:

for b4_file in ./*_B4.TIF; do
    b5_file="${b4_file%_B4.TIF}_B5.TIF"
    ndvi_file="$HOME/Geodata/goteborg/croped/ndvi/${b4_file%_B4.TIF}_NDVI.TIF"

    if [ ! -f "$b5_file" ]; then
        printf 'Expected to find "%s" to go with "%s", but did not\n' "$b5_file" "$b4_file" >&2
        continue
    fi

    # do whatever it is you need to do with "$b4_file" and "$b5_file"

    gdal_calc.py -A "$b4_file" -B "$b5_file" --type=Float32 \
        --outfile="$ndvi_file --calc="(B-A)/(B+A)"

done

答案2

首先请注意,Unix 上不存在文件扩展名之类的东西。.只是另一个角色。因此,我在这里搜索大约 1/2 的文件,去掉名称的末尾,准备将其放回去(以两种不同的方式)。

这会起作用,但可能会有一些潜在的错误。

for f in *_B5.TIF   
do 
    i="$(echo "$f" | sed -r -e 's/(.*)_B5.TIF/\1/')"
    … ${i}_B4_SA.TIF -B ${i}_B5_SA.TIF …
done

这应该更稳健

find . -iname "*_B5.TIF" -print0 | sed -0r -e 's/(.*)_B5.TIF/\1/' | xargs -0 -i … {}_B4_SA.TIF -B {}_B5_SA.TIF …

请测试一下,因为我没有(可能是一些小错误)。并且没有错误检查。您的程序必须检查是否存在错误匹配。

答案3

当您使用 Bash 时,您可以使用参数扩展截断结尾并将文件名的公共部分保存在新变量中:

for f in *_B4.TIF ; do
    i="${f%_B4.TIF}"
    gdal_calc.py -A "${i}_B4.TIF" -B "${i}_B5.TIF" --outfile=".../${i}_NDVI.TIF"
done

相关内容