如果目标文件不存在,如何退出shell脚本

鉴于下面的脚本,我想避免执行pipe道,如果一个文件不存在。

如果没有findtxt文件,我该如何直接退出脚本?

ls */*.txt | grep ab1 | awk '{print $1, $1}' | sed "s/\"/\"\"/g" | xargs -L1 mv 

你可以用类似的东西检查文件的存在:

 if [[ -f x.txt ]] ; then echo file exists. fi 

如果没有,退出就可以了:

 if [[ ! -f x.txt ]] ; then echo 'File "x.txt" is not there, aborting.' exit fi 

-f <file>只是您可以使用的许多条件表达式之一 。 如果你在CONDITIONAL EXPRESSIONS下查看bash man-page,你会看到其中的一大堆。


如果(如问题更新中所述)您希望检查通配符是否生成文件,则可以简单地展开它,丢弃错误。 如果没有,你会得到一个空字符串,可以用-z来检测:

 if [[ -z "$(ls -1 */*.txt 2>/dev/null | grep ab1)" ]] ; then echo 'There are no "*/*.txt" files.' exit fi 

请注意,我已经使用-1来强制每行一个文件,即使Linux ls在默认情况下如果输出设备不是终端(从内存)那样做。 这只是为了防止在这种情况下在每行强制一个的机器上尝试这种方法。


请记住,如果你的文件名中有空格,那么使用ls ,然后用awk来提取第一列是不会工作得太好的。 例如,文件abc ab1.txt将导致只提取abc位。

使用-print0 find结合xargs-0是通常正确处理可能有“特殊”字符的文件的方法。 还有很多其他选项可以帮助您确保仅处理所需的文件,例如-maxdepth可以限制目录树的距离,以及-name可以正确地过滤文件名。

但是,如果您知道您将永远不会拥有这些类型的文件,那么可以使用ls解决方案,只要确保您对其缺点感到满意即可。

使用test

一种快速而简短的存在测试方法:

 test -e $FILENAME || exit 

你可以通过以下方式来链接它:

 test -e $FILENAME && something | something-else 

在这种情况下,只有在文件存在的情况下才会执行something-else

例如:

 ➤ test -e ~/.bashrc && echo True || echo False True ➤ test -e ./exists-not && echo True || echo False False 

另外:请注意, [test的别名。 [[由bash定义并且可以在bash manpage中找到]的语义

然而…

…你可能更好使用find来获取你的文件:

 find ./ -maxdepth 2 -name "*ab1*.txt" -exec do-something-to-filename '{}' \; 

由于ls的输出不能被可靠地解析。 如果文件名存在,这也只会执行do-something-to-filename这个命令,这正是我想要的。

{}将被替换为每次调用do-something-to-filename

find ... -exec ...find ... -print0 | xargs -0 ... find ... -print0 | xargs -0 ...通常很好,但你可以直接使用bash的nullglob选项来使用glob:

 bash-3.2$ echo *foo *foo bash-3.2$ shopt -s nullglob bash-3.2$ echo *foo bash-3.2$ 

根据脚本的其余部分,您可能会也可能不希望使用shopt -u nullglob重新取消设置。

我试过这个,这对我有效

 test -s <<your file path>> && exit 0 || <<things to do when file NOT exists>> 

请注意,当文件不存在时,我确实正在退出