鉴于下面的脚本,我想避免执行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>>
请注意,当文件不存在时,我确实正在退出