【问题标题】:How can I preserve line breaks in bash when comparing output to regex?将输出与正则表达式进行比较时,如何在 bash 中保留换行符?
【发布时间】:2018-02-15 06:50:36
【问题描述】:

如果我有以下代码:

if [[ "$(cat myfile)" =~ ^scripts\/.* ]]; then
  echo YES
else
  echo NO
fi

而“myfile”包含以下内容:

hot/warm
scripts/whatever
cold/cool

我运行代码时的结果是“NO”,但我希望它是 YES。

如果我通过重新排序内容来更改“myfile”,以便首先出现“scripts/whatever”,如下所示:

scripts/whatever
hot/warm
cold/cool

那么当我运行我的脚本时的结果确实是 YES。这是有问题的,因为我希望我的脚本检测该正则表达式模式是否出现在任何内容行上,而不仅仅是第一行。

【问题讨论】:

  • 为什么不直接使用grep -q '^scripts/.*$' myfile

标签: regex bash newline cat


【解决方案1】:

如果你想测试“scripts”出现在字符串的开头出现在一行的开头,那么执行这个:

[[ "$(< myfile)" =~ (^|$'\n')scripts/.* ]]

注意事项

  • 您不需要在 bash 正则表达式中转义斜杠
  • $(&lt; file) 是一种 bash 内置方式来执行 $(cat file)

在这种情况下,使用 grep 作为 anubhava 演示可能更清晰、更快。

【讨论】:

    【解决方案2】:

    你的情况:

    [[ "$(cat myfile)" =~ ^scripts\/.* ]]; 
    

    正在检查完整文件数据的正则表达式(您使用cat myfile 命令提取),因此它只会在文件内容以scripts/ 开头时匹配。

    不是每行开头都匹配。

    为此,您可以将 grep 与您的 git diff 命令一起使用(参见下面的 cmets):

    if git diff | grep -q '^scripts/'; then
      echo 'YES'
    else
      echo 'NO'
    fi
    

    【讨论】:

    • 我以cat myfile 为例,但实际上我打算执行git diff 命令,而不是使用真正的文件进行grep。
    • 如果您使用的是git diff,请使用git diff | grep -q 'scripts/
    • 谢谢,不过,我认为您仍然错误地将 git diff 代码块留在了“myfile”中。
    【解决方案3】:

    如果您想避免使用 grep,可以使用 while-read-do 循环,如下所示。

    cat myfile | while read LINE; do
      if [[ "$LINE" =~ ^scripts\/.* ]]; then
        echo YES
      else
        echo NO
      fi
    done
    

    我在您发布的文件的两个版本上运行此程序并得到以下输出(与您发布它们的顺序相同):

    YES
    NO
    NO
    

    NO
    YES
    NO
    

    唯一的问题是它会在文件中的每一行打印一次,因此如果您只想打印一次,您可能希望在 YES 条件下使用break

    【讨论】:

      猜你喜欢
      • 2021-01-09
      • 2020-02-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多