if
语句,但不了解如何在脚本中使用grep
。我知道grep
看起来会像这样grep ^ schemas.txt
我觉得这应该比我做起来容易得多。
我' m在
if
语句上收到“参数过多”错误。我摆脱了grep -q
之间的空间,然后得到了预期的错误二进制运算符。 if [ grep -q ^ schemas.txt ]
then
echo "Schema already exists. Please try again"
exit 1
else
echo "$@" >> schemas.txt
fi
#1 楼
grep
如果发现某物(零)与未发现任何物(非零),则返回不同的退出代码。在if
语句中,零退出代码映射为“ true”,非零退出代码映射为false。另外,grep有一个-q
参数,它不输出匹配的文本(只返回退出状态代码)。因此,您可以像这样使用grep:
if grep -q PATTERN file.txt; then echo found else echo not found fi 之类的操作时,事实证明if [ -z "$var" ]…
实际上是您正在运行的命令,就像grep。在我的系统上,它是[
。 (从技术上讲,您的外壳可能内置了它,但这是一种优化。它的行为就像是一条命令一样)。它的工作方式相同,/usr/bin/[
返回零退出代码为true,返回非零退出代码为false。 ([
与test
是相同的东西,除了结尾[
)评论
为什么if语句不需要括号?我没有它就可以工作,但是不明白为什么。我还能在没有括号的情况下嵌套它吗?
–劳伦
2012-09-18 18:47
@Lauren你错过了快速笔记吗? [不是if语法的一部分,(从概念上讲,它是您正在运行的命令,就像grep一样
–德罗伯特
2012年9月18日19:06
@Lauren您不会在[内使用grep,而是使用一个或另一个,这取决于要检查的条件。 (您可以在if,btw,if中使用任何命令,只要检查退出代码。)…嗯,我想您可能想出了在[内使用grep的原因,但这将是一个相当复杂的脚本及其不是正常的事情。
–德罗伯特
2012-09-18 19:21
仅供参考,请运行ls -l / usr / bin / \ [和man [以查看[是一个与其他程序一样的程序,它看起来像是一个语法元素-这应该使它变得显而易见并且易于理解。 (为方便起见,[也是bash,dash和其他命令中的内置命令-但这仍然是命令)。也可以尝试在bash中键入-all [。
–cas
2012-09-18 22:56
@AlexanderCska如果要grep打印匹配的行(例如,将它们通过管道传输到某处),则省略-q,该选项告诉grep保持安静(不打印匹配的行)。
–德罗伯特
19年7月22日在16:00
#2 楼
另一种简单的方法是使用grep -c
。 输出(不返回退出代码),即与模式匹配的行数,因此,如果没有匹配,则为0,如果有匹配,则为1或更多。
因此,如果您想检查模式是否匹配3次或更多次,则可以执行以下操作:
if [ "$(grep -c "^" schemas.txt)" -ge 3 ]; then
...
评论
更准确地说,如果仅发现一次,它将输出1。要输出1(无论找到的匹配项多少),请改用grep -cim1。
–manatwork
13年4月29日在10:26
此方法还可用于区分grep错误和grep“找到0次模式”。 (尽管没有使用确切的if语句,但我认为需要一个变量)
–埃文·本恩
19年4月3日在5:27
grep -cim1的说明:-c表示打印计数,-i表示不区分大小写(因此,如果不需要,请删除此选项),-m表示在此行匹配之后停止读取。因此,它实际上意味着grep --count --ignore-case --max-count = 1。
–提交
20-10-6在4:29
#3 楼
我知道我为此迟到了,但是我喜欢这个简短的版本:grep -q ^ schemas.txt && echo "Schema already exists. Please try again" || echo "$@" >> schemas.txt
#4 楼
如果要捕获文件的第一个单词,则需要在grep中添加-zw
if grep -qzw "^" file
then
...
else
...
fi
如果没有
-z
,我们将获得一行的第一个单词。没有-w
,我们会得到部分单词。#5 楼
如果要在方括号中使用它,可以执行以下 if [ `grep -q PATTERN file.txt` ]; then
echo found
else
echo not found
此逻辑适用于所有命令,只需将命令放在反引号内(选项卡上方的按钮或Esc按钮的下方或1按钮的左侧)
评论
您需要引用`grep -q PATTERN file.txt`,否则将应用split + glob运算符,这将对包含$ IFS字符或通配符的任何输出产生问题。更一般而言,如果cmd在stdout上输出至少一根非空行,则[“`cmd`”]将返回true(如果输出NUL字节,则可能会出现问题)。这意味着外壳将必须将整个输出存储在内存中并等待其完成。使用if cmd | grep -q。在这方面可能更可取。
–StéphaneChazelas
16年8月24日在13:01
该命令根本没有意义。 -q开关的作用是抑制grep的输出。您的意思是:在file.txt中检查PATTERN,抑制任何输出,然后根据是否找到PATTERN设置返回状态。然后,忽略返回状态,获取命令输出(我们被迫为空),应用分词和文件glob扩展(根本不包含任何参数),然后使用仅一个参数运行[(aka test)命令- -即[],然后由于会导致错误,请回显“未找到”。 @StéphaneChazelas,我想念什么吗?
–通配符
16 Sep 16 '22:51
@Wildcard,您是对的,我显然忽略了-q。该注释对[`grep PATTERN file.txt`]有意义,但正如注释中所暗示的,如果PATTERN仅可匹配空行,则[“`grep -n PATTERN file.txt`”]会更好。虽然这里当然是您想要的grep -q PATTERN file.txt。
–StéphaneChazelas
16-09-17在6:47
评论
丢掉[…],它将起作用。虽然您可能想引用模式:if grep -q“ ^ $ 1” schemas.txt;然后...使用Bash的“组命令”功能的一线解决方案:stackoverflow.com/questions/6550484/…
Bash oneliner。如果在文件content.txt中找到字符串“ foo”,则运行命令work.sh,否则不执行任何操作:cat content.txt | grep“ foo” && work.sh