鉴于下面的脚本,如果文件不存在,我想避免执行管道。
如果找不到txt文件,如何立即退出脚本?
ls */*.txt | grep ab1 | awk '{print $1, $1}' | sed "s/\"/\"\"/g" | xargs -L1 mv
答案 0 :(得分:39)
您可以使用以下内容检查文件是否存在:
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>
只是您可以使用的众多条件表达式的一个。如果您查看bash
下的CONDITIONAL EXPRESSIONS
人工页面,您会看到其中的一大部分内容。
如果(如问题更新中所述)您希望检查通配符是否会产生文件,您可以简单地展开它,丢弃错误。如果没有,您最终会得到一个空字符串,可以使用-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
提取第1列将无法正常工作。例如,文件abc ab1.txt
将导致仅提取abc
位。
将find
与-print0
结合使用,将xargs
与-0
结合使用,是正确处理可能包含“特殊”字符的文件的常用方法。您可以为find
提供许多其他选项,以确保仅处理所需的文件,例如-maxdepth
以限制目标树的走向,并-name
正确过滤文件名。
但是,如果您知道您将永远不会拥有这些类型的文件,那么可以使用ls
解决方案,只需确保您对其缺点感到满意。< / p>
答案 1 :(得分:8)
test
快速而简短的存在测试方法:
test -e $FILENAME || exit
您可以通过执行以下操作来链接:
test -e $FILENAME && something | something-else
在这种情况下something
和something-else
仅在文件存在时才会执行。
例如:
➤ test -e ~/.bashrc && echo True || echo False
True
➤ test -e ./exists-not && echo True || echo False
False
旁白:请注意,[
是test
的别名。 [[
的语义由bash定义,可以找到on the bash manpage
...您最好使用find
来获取文件:
find ./ -maxdepth 2 -name "*ab1*.txt" -exec do-something-to-filename '{}' \;
由于ls
的输出无法可靠地解析。如果文件名存在,这也只会执行命令do-something-to-filename
,这是我认为你想要做的。
{}
时, do-something-to-filename
将替换为文件名。
答案 2 :(得分:0)
find ... -exec ...
或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
重新取消设置。
答案 3 :(得分:0)
我试过这个,这对我有用
test -s <<your file path>> && exit 0 || <<things to do when file NOT exists>>
请注意,我实际上在文件不存在时退出