grep是否支持字符串正则匹配?Shell脚本匹配方案问询
在Shell脚本中用grep搜索字符串的问题
grep是否支持搜索字符串?
grep既可以搜索文件,也能直接处理字符串,不需要局限于文件输入。你可以通过管道或者Here字符串的方式给grep传入字符串内容。
你提供的代码不可行,问题出在这些地方:
--file=$line参数错误:--file选项是用来指定包含搜索模式的文件,不是传入要搜索的字符串。你这里把变量line作为文件路径传入,grep会尝试打开名为该字符串内容的文件,必然失败。- 正则表达式存在问题:
something*会匹配something后面跟任意多个g(*作用于前一个字符),你实际要匹配的是something后的任意内容,应该写成something.*。[UPLOAD_REQUEST_RESULTS_DOWNLOADED, UPLOAD_REQUEST_CANCELLED]是字符集匹配,会匹配括号里的任意单个字符,而非完整的两个短语。正确写法是用分组加或逻辑:(UPLOAD_REQUEST_RESULTS_DOWNLOADED|UPLOAD_REQUEST_CANCELLED)。- 你用了
-E选项(扩展正则),正则里的{}不需要转义,写成[0-9]{4}即可,不用[0-9]\{4\}。
修正后的代码示例
如果要统计匹配次数,可以这样写:
line="INSERT INTO something VALUES('v1','v2','UPLOAD_REQUEST_RESULTS_DOWNLOADED',1,'v3','2023-07-15 23:36:53.0')" val=$(echo "$line" | grep -Ec "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 "$val"
或者用Here字符串更高效:
val=$(grep -Ec "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")
逐行遍历文件并匹配修改的场景
如果你是逐行遍历文件,需要匹配并修改特定行,可以用以下几种方式:
方式1:用grep配合sed直接修改文件(推荐)
如果不需要复杂逻辑,直接用sed批量处理:
sed -i '/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]/s/要替换的内容/新内容/' your_file.txt
-i参数直接修改原文件,s/旧内容/新内容/是替换规则。
方式2:逐行读取处理
如果需要更复杂的逻辑(比如先判断再执行不同操作),可以用while循环:
while IFS= read -r line; do if echo "$line" | grep -qE "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]"; then # 匹配成功,执行修改操作(示例为替换) new_line=$(echo "$line" | sed 's/要替换的内容/新内容/') echo "$new_line" else # 不匹配,直接输出原行 echo "$line" fi done < your_file.txt > temp_file.txt && mv temp_file.txt your_file.txt
这里用grep -q只返回匹配状态,不输出内容,效率更高;最后把结果写入临时文件再替换原文件,避免直接修改导致的文件损坏问题。
内容的提问来源于stack exchange,提问作者Vishwad
相关产品推荐
相关产品推荐

