鉴于下面的脚本,如果文件不存在,我想避免执行管道。
如果找不到文本文件,如何立即退出脚本?
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>
是您可以使用的众多条件表达式之一。如果您查看 下的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
with -print0
,结合 withxargs
是-0
正确处理其中可能包含“特殊”字符的文件的常用方法。您可以提供许多其他选项find
来确保只处理所需的文件,例如-maxdepth
限制您进入目录树的位置,以及-name
正确过滤文件名。
但是,如果您知道您永远不会拥有这些类型的文件,那么使用该ls
解决方案可能没问题,只要确保您对它的缺点感到满意。
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 定义,可以在 bash 手册页上找到
...您最好使用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 ...
通常很好,但是您可以使用 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>>
请注意,当文件不存在时,我实际上正在退出