如何在bash中匹配此字符串?

时间:2015-11-09 12:51:34

标签: regex bash

我正在逐行读取bash中的文件。我需要打印具有以下格式的行:

不关心<<<至少一个字符>>>不在乎。

这些都是我尝试过的方式,但没有一种方法有效:

   if [[ $line =~ .*<<<.+>>>.* ]]; then
      echo "$line"
   fi

语法不正确

这两个语法正确无法正常工作

   if [[ $line =~ '.*<<<.+>>>.*' ]]; then
      echo "$line"
   fi

而且:

   if [[ $line == '*<<<*>>>*' ]]; then
      echo "$line"
   fi

那么如何告诉bash只打印那种格式的行? PD:我已经测试并打印了所有线路工作正常。

4 个答案:

答案 0 :(得分:2)

不需要正则表达。文件名模式可以正常工作:

if [[ $line == *"<<<"?*">>>"* ]]; then ...
  • * - 匹配零个或多个字符
  • ? - 只匹配一个字符
  • "<<<"">>>" - 文字字符串:需要引用尖括号,因此bash不会将它们解释为此字符串重定向。
$ line=foobar
$ [[ $line == *"<<<"?*">>>"* ]] && echo y || echo n
n
$ line='foo<<<>>>bar'
$ [[ $line == *"<<<"?*">>>"* ]] && echo y || echo n
n
$ line='foo<<<x>>>bar'
$ [[ $line == *"<<<"?*">>>"* ]] && echo y || echo n
y
$ line='foo<<<xyz>>>bar'
$ [[ $line == *"<<<"?*">>>"* ]] && echo y || echo n
y

答案 1 :(得分:1)

为了获得最大的兼容性,将单个引号中的正则表达式模式定义为单独的变量始终是一个好主意,然后使用它不加引号。这对我有用:

re='<<<.+>>>'
if [[ $line =~ $re ]]; then
    echo "$line"
fi

顺便说一下,我摆脱了冗余的前导/尾随.*

当然,我假设您有正当理由以原生bash处理该文件(如果没有,只需使用grep -E '<<<.+>>>' file

答案 2 :(得分:1)

<<<<<<>>>在shell中很特殊,需要引用:

[[ $line =~ '<<<'.+'>>>' ]]
不过,

.+不应该被引用以保持其特殊含义。

您不需要.*匹配中的前导=~,但您需要它们(或其等价物)的模式:

[[ $line == *'<<<'?*'>>>'* ]]

使用grep提取行更快:

grep -E '<<<.+>>>' input-file

答案 3 :(得分:0)

我甚至不明白你为什么每行读取文件行。我刚刚在bash提示符中启动了以下命令,它运行正常:

grep "<<<<.+>>>>" test.txt

其中test.txt包含以下数据:

<<<<>>>>
<<<<a>>>>
<<<<aa>>>>

命令的结果是:

<<<<a>>>>
<<<<aa>>>>