【问题标题】:Escaping slash "\" in grep在 grep 中转义斜杠“\”
【发布时间】:2017-10-17 11:07:20
【问题描述】:

我有一行文件:

"H:\Check\WP_20140511_029.mp4"

与其他行一起。我想删除这些指示H:\Check 目录的行。我试过了

grep -v ".*H:\\Check.*" testout.txt > testout2.txt

但它并没有删除那些行。我的正则表达式 .*H:\\Check.* 有什么问题。 regex101 shows 我的正则表达式正确匹配该行。

【问题讨论】:

    标签: regex linux bash shell grep


    【解决方案1】:

    你可以使用:

    grep -v 'H:\\Check' testout.txt > testout2.txt
    

    使用单引号很重要,以避免过度转义反斜杠。

    使用双引号等效的命令会是这样的:

    grep -v "H:\\\Check" testout.txt > testout2.txt
    

    编辑:

    \\ 在双引号中相当于单个反斜杠,因为 shell 扩展仅在双引号中发生。从这些echo 命令可以看出:

    echo "H:\\Check"
    H:\Check
    
    echo 'H:\\Check'
    H:\\Check
    

    【讨论】:

    • 为什么我们需要三个斜杠\\` inside double quotes and two slashes \` 在单引号内。还有为什么我们可以忽略.*?正则表达式不应该匹配整行吗?
    • grep 正则表达式不需要匹配整行。只需匹配您已知的模式n
    • 针对反斜杠的单/双引号处理行为的差异进一步更新了答案。
    • 嗯...我认为转义后应该是H:\Check,而不是H:\\Check。为什么后者是正确的而前者不是?只是想让我更清楚......
    • 因为\C 只是表示转义的 C 字符而不是后跟 C 的反斜杠
    【解决方案2】:

    首先,使用 grep 时,您不需要指定任何字符 .* 组合。 Grep 已经构建用于查找您的短语(示例 grepping for he 在一个文件中包含一行 Hi there 将返回整行,而无需像您的正则表达式那样使用 .*he.*

    第二(我看到 anubhava 在我打字时击败了我),反斜杠转义的工作方式不同,具体取决于您对引号的使用。

    如果您使用单引号,则单个反斜杠将转义第二个,因此您需要两个,因此您的正则表达式将为 H:\\Check

    如果您使用双引号(与您一样),则反斜杠将在评估引号时转义另一个反斜杠,然后生成的反斜杠将尝试转义 C(这甚至与我们想要的不相近),因此您实际上需要第三个反斜杠才能正确转义。

    如果你想不带引号(在我看来这不是很好的风格,但因为你只有一个短语,如果你真的想的话,你可以这样做),出于类似的原因,你实际上需要 4 个反斜杠。 \ 通常会让命令继续到下一行,所以第一个转义第二个,第三个转义第四个,然后评估 grep 时只有 2 个,这是正确转义的。

    您应该尝试更多地使用 Grep 来看看它的功能,只要您知道语法,它基本上可以执行您想要的任何搜索(以及更多您永远不会想要的搜索)。

    编辑:修正了一些语法,谢谢。我不知道 * 在这些答案中将文本转换为斜体。

    【讨论】:

    • 你的“你好”的例子不太正确;你能用反引号(`)来表示一个文字字符串吗?除此之外,星号被解释为斜体而不是文字星号。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-10
    • 2020-12-22
    • 1970-01-01
    相关资源
    最近更新 更多