Bash复合条件,带有通配符和文件存在性检查
我已经掌握了Bash复合条件的基本知识,并且已经阅读了一些检查通配符文件是否存在的不同方法,但是这一种方法让我无法理解,所以我想我应该寻求帮助 我需要: 1.)检查是否存在与模式匹配的文件 及 2.)检查其他文件中是否存在文本 我知道有很多方法可以做到这一点,但我真的没有知识来区分它们的优先级(如果你有这些知识,我也会有兴趣阅读) 首先想到的是使用find for#1和grep for#2 大概是Bash复合条件,带有通配符和文件存在性检查,bash,file,shell,grep,conditional,Bash,File,Shell,Grep,Conditional,我已经掌握了Bash复合条件的基本知识,并且已经阅读了一些检查通配符文件是否存在的不同方法,但是这一种方法让我无法理解,所以我想我应该寻求帮助 我需要: 1.)检查是否存在与模式匹配的文件 及 2.)检查其他文件中是否存在文本 我知道有很多方法可以做到这一点,但我真的没有知识来区分它们的优先级(如果你有这些知识,我也会有兴趣阅读) 首先想到的是使用find for#1和grep for#2 大概是 if [ `grep -q "OUTPUT FILE AT STEP 1000" ../log/m
if [ `grep -q "OUTPUT FILE AT STEP 1000" ../log/minimize.log` ] \
&& [ `find -name "jobscript_minim\*cmd\*o\*"` ]; then
echo "Both passed! (1)"
fi
但奇怪的是,这失败了:
if `grep -q "OUTPUT FILE AT STEP 1000" ../log/minimize.log` ;then
echo "Text passed!"
fi
if `find -name "jobscript_minim\*cmd\*o\*"` ;then
echo "File passed!"
fi
都通过了
我读了一些书,看到有人谈论在if语句中多个文件名匹配通配符的问题。最好的解决办法是什么?(在回答我的问题时,我假设你在这个过程中也会尝试一下这个问题)
有什么想法/解决方案/建议吗?让我们先来看看您的尝试失败的原因:
if [ `grep -q …` ];
这将在反勾号之间运行grep
命令,并在条件命令内插入输出。由于grep-q
不产生任何输出,就好像您编写了if[]代码>
条件应该测试grep
的返回代码,而不是它的输出。因此,它应该简单地写为
if grep -q …;
find
命令即使没有找到任何内容,也会返回0(即true),因此此技术不起作用。通过收集其输出并将其与空字符串进行比较,测试其输出是否为空:
if [ "$(find …)" != "" ];
(如果[-n”$(查找…)]
,则等效测试为)
注意这里的两件事:
- 我使用了
$(…)
而不是反勾号。它们是等价的,只是backticks需要在它们内部进行奇怪的引用(特别是当您试图嵌套它们时),而$(…)
是简单可靠的。只需使用$(…)
并忘记反勾号(除了需要在双引号内写入\`
)
$(…)
周围有双引号。这真的很重要。如果没有引号,shell将把find
命令的输出分解为单词。如果find
打印,比如说,两行dir/file
和dir/otherfile
,我们需要If[“dir/file dir/otherfile”=“”]代码>待执行,而不是如果[dir/file dir/otherfile=”“]代码>这是一个语法错误。这是shell编程的一般规则:始终在变量或命令替换前后加上双引号。(变量替换是$foo
或${foo}
;命令替换是$(command)
)
现在让我们看看您的要求
检查是否存在与模式匹配的文件
如果您递归地在当前目录或其下的任何目录中查找文件,则find-name“PATTERN”
是正确的。然而,如果目录树变大,它的效率就会降低,因为当我们只关心一个匹配项时,它会花费大量时间打印所有匹配项。一种简单的优化方法是,通过管道将第一条管线插入头部-n1
find
一旦意识到head
对它要说的内容不再感兴趣,就会停止搜索
如果[“$(查找-名称“jobscript_minimicmdo”| head-n 1)!=”
(请注意,双引号已经保护通配符不被扩展。)
如果您只在当前目录中查找文件,假设您有GNU find(Linux、Cygwin和Gnuwin32上就是这种情况),一个简单的解决方案是告诉它不要递归到比当前目录更深的地方
如果[“$(find-maxdepth 1-name“jobscript_minim*cmd*o*”)!=”
还有其他更具可移植性的解决方案,但编写起来更复杂
检查其他文件中是否存在文本
您已经获得了正确的grep
命令。请注意,如果要搜索文字字符串,应使用grep-F
;如果您正在寻找一个regexp,grep-E
的语法比普通的grep
更为合理
总而言之:
if grep -q -F "OUTPUT FILE AT STEP 1000" ../log/minimize.log &&
[ "$(find -name "jobscript_minim*cmd*o*")" != "" ]; then
echo "Both passed! (1)"
fi
bash 4
请添加一些解释性文字。
shopt -s globstar
files=$(echo **/jobscript_minim*cmd*o*)
if grep -q "pattern" file && [[ ! -z $files ]];then echo "passed"; fi
for i in filename*; do FOUND=$i;break;done
if [ $FOUND == 'filename*' ]; then
echo “No files found matching wildcard.”
else
echo “Files found matching wildcard.”
fi