0

我正在开发一个脚本来处理和移动掉到某个文件夹中的压缩文件。

只要放入文件夹中的是压缩文件,该脚本就可以完美运行。但是,如果脚本在没有压缩文件来处理的情况下执行 bash 函数 ${f%.gz} 会产生意想不到的结果。

这是脚本,之后是问题案例的示例:

FILES="$INGEST_DIR/*.gz"

for f in $FILES
do
    JUSTFILENAME=${f##/*/}
    syslog -s -l n "Archiving \"$JUSTFILENAME\""
    UNZIPPEDPATH=${f%.gz}
    syslog -s -l n "Moving \"$UNZIPPEDPATH\""
    UNZIPPEDNAME=${UNZIPPEDPATH##/*/}
    syslog -s -l n "    to \"ASR_DIR/$UNZIPPEDNAME\""
    syslog -s -l n "gunzip-ing $f"
    gunzip $f
    mv "$UNZIPPEDPATH" "$ASR_DIR/$UNZIPPEDNAME"
done

同样,如果目标目录中至少有一个 .gz 文件,它就可以完美运行。

如果没有任何 .gz,但目录中有其他文件(由于其他原因必须存在)$FILES 包含扩展的 $INGEST_DIR 加上 /*.gz,如下所示:

INGEST_DIR=/path/to/foo
FILES="$INGEST_DIR/*.gz"
echo $FILES

将会呈现

/path/to/foo/*.gz

这并不是特别糟糕,除了

for f in $FILES
do
    UNZIPPEDPATH=${f%.gz}
    echo $UNZIPPEDPATH
done

产量

somefile.txt someotherfile.exe yetsomeotherfile.dat

那么,如果没有这样的压缩文件要处理,是否有一种优雅的方式不进行迭代?我的脚本运行良好,因为我刚刚从这个SO question & answer 中了解了 ${f##/*/} 和 ${f%.gz} ,所以我认为可能有比

FILES="$INGEST_DIR/*.gz"

开始事情......或者在进入 for 循环之前立即做一些事情。

4

2 回答 2

2

用于find获取文件列表:

for f in $(find . -type f -name "*.gz"); do

done

要将匹配限制在当前目录,您可以说:

find . -maxdepth 1 -type f -name "*.gz"
于 2013-08-07T10:06:38.563 回答
1

如果您使用的是 bash,则可以在循环之前设置 nullglob:

shopt -s nullglob
for f in $FILES

- - 添加 - -

另一种方法是使用 while read 和 process 替换:

while IFS= read -r f; do
    ...
done < <(command)

where command 可以通过使用 find 或 compgen,只有 find 可以更特定于文件:

find -type f -name '*.gz'
compgen -G '*.gz'

如果我们在循环中读取输入,我们可以在打开文件时使用其他 FD:

while IFS= read -ru 4 f; do
    ...
done 4< <(command)
于 2013-08-07T10:05:09.307 回答