![BASH - grep - 在命令行上运行,但不在脚本上运行](https://linux22.com/image/1274451/BASH%20-%20grep%20-%20%E5%9C%A8%E5%91%BD%E4%BB%A4%E8%A1%8C%E4%B8%8A%E8%BF%90%E8%A1%8C%EF%BC%8C%E4%BD%86%E4%B8%8D%E5%9C%A8%E8%84%9A%E6%9C%AC%E4%B8%8A%E8%BF%90%E8%A1%8C.png)
我试图获取脚本中的出现次数,当在命令行上运行命令时,它可以正常工作,但在脚本中却不行。两个变量都已初始化。FILE_PATH 是文件的绝对路径,VARIABLE_NAME 是 firstName 或 lastName 之类的东西。
VARIABLE_NAME="_firstName"
grep -cP "\(this\.|\s\){1}$VARIABLE_NAME" $FILE_PATH
当我从脚本中取出 $VARIABLE_NAME 并将其直接替换为我要查找的内容时,它会按预期工作,因此它是替换后的东西。
有什么想法我可以尝试吗?
答案1
问题似乎出在你的正则表达式中。你能告诉我们你想要匹配什么吗?
如果您尝试匹配这样的构造:
this.contentOfVar
contentOfVar
尝试以下方法:
grep -cP "(this\.|\s)$VARIABLE_NAME" $FILE_PATH
这在 GNU grep 中有效。您不必指定{1}
,因为默认值为 1。启用标志-P
后,\(
和\)
将匹配字符串中的文字括号,因为这是 perl 行为。
答案2
看起来问题出在正则表达式转义上。下面是一个完整的工作示例,说明如何执行此类操作。
#!/bin/bash
VARIABLE_NAMES=(testOne testTwo)
RE="(this\.|\s){1}"
cat > ./testfile.txt <<EOF
this.testOne
this.testTwo
this.testTwo
this.testOne
this.testTwo
EOF
for VARIABLE_NAME in ${VARIABLE_NAMES[@]}; do
grep -cP "${RE}${VARIABLE_NAME}" testfile.txt
done
exit 0
答案3
为了补充其他人的答案,我建议使用单引号,除非你明确需要变量中的某些内容。例如:
#!/usr/bin/env bash
dosomething | grep -cP 'some stuff'${SOMEVARIABLE}'more stuff';
如果正则表达式中需要单引号,它看起来会更丑一些:
# ...
dosomething | grep -cP 'some stuff'"'"'this part has a single-quote around it'"'"${SOMEVARIABLE}'more stuff';
使用单引号的好处是您不必转义内容。
-布莱恩
答案4
它与转义引号和斜线有关:
VARIABLE_NAME="_firstName"
FILE_PATH="/tmp/*"
echo grep -cP \"\\\(this\\\.\|\\\s\\\)${VARIABLE_NAME}\" $FILE_PATH
grep -cP \"\\\(this\\\.\|\\\s\\\)${VARIABLE_NAME}\" $FILE_PATH
我添加了回声作为示例来展示它实际上是如何解释的。