Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 如何在使用${f%.gz}语法时处理不匹配的文件_Bash_File_Parsing_Url - Fatal编程技术网

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

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

只要放入文件夹的是压缩文件,脚本就可以正常工作。但是,如果脚本在没有可处理的压缩文件时执行,则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包含扩展的$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