shell “grep”可以在字符串中找到正则表达式匹配吗?还是只搜索文件

sauutmhj  于 2023-08-07  发布在  Shell
关注(0)|答案(2)|浏览(88)

我正在创建一个shell脚本来查找字符串中的模式。“grep”会搜索字符串吗?还是只在文件中搜索?

# does this work and will grep find the pattern?
line="INSERT INTO something VALUES('v1',v2','UPLOAD_REQUEST_RESULTS_DOWNLOADED',1,'v3','2023-07-15 23:36:53.0')"
val=$(grep -Ec --regexp='INSERT INTO something*[UPLOAD_REQUEST_RESULTS_DOWNLOADED, UPLOAD_REQUEST_CANCELLED].*[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\} [0-9]\{2\}:[0-9]\{2\}:[0-9]\{2\}\.[0-9]' --file=$line)
echo "$val"

字符串
如果没有,我如何在shell脚本中的字符串中搜索模式(使用正则表达式)?问题是,我在文件中逐行迭代,这就是为什么我要搜索一行。我只需要修改特定的行。

olmpazwi

olmpazwi1#

Bash模式匹配

Bash(和Zsh)可以直接使用[[ "input" =~ pattern ]]执行regexp。
我建议总是把模式放在一个变量中。避免围绕模式的引用问题。
为了你的榜样

line="INSERT INTO something VALUES('v1',v2','UPLOAD_REQUEST_RESULTS_DOWNLOADED',1,'v3','2023-07-15 23:36:53.0')"
pattern='INSERT INTO something.*[UPLOAD_REQUEST_RESULTS_DOWNLOADED, UPLOAD_REQUEST_CANCELLED].*([0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9])'
if [[ "$line" =~ $pattern ]]; then
  echo "match"
  echo "${BASH_REMATCH[0]}"
  echo "${BASH_REMATCH[1]}"
else
  echo "no match"
fi

字符串
$pattern周围缺少的引号是故意的和重要的。Bash中的正则表达式模式是特殊解析的,即使有空格也不需要引号。我也不得不稍微调整你的初始正则表达式。第一个“*”前缺少一个点,并删除了{}周围的反斜杠。
直接使用Bash执行正则表达式的一个主要好处(除了不必派生外部命令的性能好处之外)是您可以使用捕获组!当模式匹配时,Bash将设置一个特殊的数组BASH_REMATCH,其中第一个元素是整个修补字符串,每个其他元素是匹配的捕获组。(对于Zsh来说,这有点不同。参见数组匹配或shell选项来模拟Bash的行为)

进程替换

如果你想使用grep,也可以使用process substitution<( command )代替herestrings。大致:执行命令并提供输出,就像它是一个文件一样。

line="INSERT INTO something VALUES('v1',v2','UPLOAD_REQUEST_RESULTS_DOWNLOADED',1,'v3','2023-07-15 23:36:53.0')"
val=$(grep -Ec --regexp='INSERT INTO something*[UPLOAD_REQUEST_RESULTS_DOWNLOADED, UPLOAD_REQUEST_CANCELLED].*[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\} [0-9]\{2\}:[0-9]\{2\}:[0-9]\{2\}\.[0-9]' <(echo "$line"))
echo "$val"


如果你只想知道grep是否匹配(-c表示,因为这里有max 1行),你也可以把它放在if中:

if grep --silent -E pattern file; then
  echo match
fi


当我们在它:regex部分[UPLOAD_REQUEST_RESULTS_DOWNLOADED, UPLOAD_REQUEST_CANCELLED]并不像你所期望的那样。它看起来应该匹配UPLOAD_REQUEST_RESULTS_DOWNLOADEDUPLOAD_REQUEST_CANCELLED。但是[...]是一个字符类。它匹配类中的任何字符。所以正则表达式的这一部分匹配一个字符,它是这两个单词中的任意大写字母,或者下划线,逗号或空格。
要匹配某些替代方案中的任何一个,您可以使用(UPLOAD_REQUEST_RESULTS_DOWNLOADED|UPLOAD_REQUEST_CANCELLED)

g52tjvyc

g52tjvyc2#

使用here字符串:

# does this work and will grep find the pattern?
line="INSERT INTO something VALUES('v1',v2','UPLOAD_REQUEST_RESULTS_DOWNLOADED',1,'v3','2023-07-15 23:36:53.0')"
val=$(grep -Ec --regexp='INSERT INTO something*[UPLOAD_REQUEST_RESULTS_DOWNLOADED, UPLOAD_REQUEST_CANCELLED].*[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\} [0-9]\{2\}:[0-9]\{2\}:[0-9]\{2\}\.[0-9]' <<<"$line")
echo "$val"

字符串

相关问题