Bash 如何在使用${f%.gz}语法时处理不匹配的文件
我正在开发一个脚本来处理并移动掉到某个文件夹中的压缩文件 只要放入文件夹的是压缩文件,脚本就可以正常工作。但是,如果脚本在没有可处理的压缩文件时执行,则bash函数${f%.gz}会产生意外的结果 以下是脚本,以及随后的问题案例示例:Bash 如何在使用${f%.gz}语法时处理不匹配的文件,bash,file,parsing,url,Bash,File,Parsing,Url,我正在开发一个脚本来处理并移动掉到某个文件夹中的压缩文件 只要放入文件夹的是压缩文件,脚本就可以正常工作。但是,如果脚本在没有可处理的压缩文件时执行,则bash函数${f%.gz}会产生意外的结果 以下是脚本,以及随后的问题案例示例: FILES="$INGEST_DIR/*.gz" for f in $FILES do JUSTFILENAME=${f##/*/} syslog -s -l n "Archiving \"$JUSTFILENAME\"" UNZIPPE
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包含扩展的$inset_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
那么,如果没有这样的压缩文件来处理,有没有一种优雅的方法来避免迭代呢?我的脚本运行得很好,因为我刚刚从问答中了解了${f##/*/}和${f%.gz},所以我想可能有比这更好的方法
FILES="$INGEST_DIR/*.gz"
开始时。。。或者在进入for循环之前立即执行的操作。如果使用bash,可以在循环之前设置nullglob:
shopt -s nullglob
for f in $FILES
----加----
另一种方法是使用while read和process substitution:
while IFS= read -r f; do
...
done < <(command)
如果在循环中读取输入,则在打开文件时可以使用其他FD:
while IFS= read -ru 4 f; do
...
done 4< <(command)
而IFS=read-ru 4 f;做
...
完成4<如果使用bash,可以在循环之前设置null glob:
shopt -s nullglob
for f in $FILES
----加----
另一种方法是使用while read和process substitution:
while IFS= read -r f; do
...
done < <(command)
如果在循环中读取输入,则在打开文件时可以使用其他FD:
while IFS= read -ru 4 f; do
...
done 4< <(command)
而IFS=read-ru 4 f;做
...
完成4<使用find
获取文件列表:
for f in $(find . -type f -name "*.gz"); do
done
要将匹配限制为当前目录,可以说:
find . -maxdepth 1 -type f -name "*.gz"
使用find
获取文件列表:
for f in $(find . -type f -name "*.gz"); do
done
要将匹配限制为当前目录,可以说:
find . -maxdepth 1 -type f -name "*.gz"
谢谢@devnull,我喜欢将find直接构建到循环处理程序中,因为这很清楚您在做什么。@devnull我想您也可以将IFS设置为$'\n'以防止文件名与空格分开。或者如果在Bash中,只需使用find-输入f-名称“*.gz”|而IFS=read-rf;做完成
@konsolebox您可以引用
$(…)
,这样可以处理文件名中的空格。@devnull您是说“$(…)”吗?但这只能被解析为一个字符串。@konsolebox是否尝试了引用的版本?谢谢@devnull,我喜欢将find直接构建到循环处理程序中,因为这样做很清楚。@devnull我认为您还可以将IFS设置为$'\n'以防止用空格拆分文件名。或者如果在Bash中,只需使用find-输入f-名称“*.gz”|而IFS=read-rf;做完成
@konsolebox您可以引用$(…),这样可以处理文件名中的空格。@devnull您是说“$(…)”吗?但这只能被解析为一个字符串。@konsolebox您尝试过引用的版本吗?谢谢konsolebox,它工作得很好。我将接受您的答案以帮助您的销售代表:)尽管我个人将使用@devnull给出的答案,因为从现在起6个月后重新查看脚本时,我将更容易知道发生了什么!欢迎我添加了更多的建议,以防它们也会有帮助。它们很有帮助——我在bash中仍然说不流利。。。特别是,康普根对我来说是个新手,看起来很得心应手。谢谢你,konsolebox,很好用。我将接受您的答案以帮助您的销售代表:)尽管我个人将使用@devnull给出的答案,因为从现在起6个月后重新查看脚本时,我将更容易知道发生了什么!欢迎我添加了更多的建议,以防它们也会有帮助。它们很有帮助——我在bash中仍然说不流利。。。特别是,康普根对我来说是个新手,看起来很得心应手。我同意当涉及到文件时,你应该使用find
工具的强大功能,至于${foo%boo}
语法,如果它在foo
变量中没有找到boo
,它将返回foo
不变。该语法只是试图从foo
字符串的末尾切断boo
。我同意当涉及到文件时,您应该使用find
工具的功能,就像${foo%boo}
语法一样,如果它在foo
变量中没有找到boo
,它将返回foo
不变。该语法只是试图从foo
字符串的末尾切断boo
。