陷入正则表达式语法困境

陷入正则表达式语法困境

我正在编写一个基本的 shell 脚本,并获得了一个数据文件,我需要对其进行一些编辑才能使用它。问题是它有多行重复,甚至有单词,所以我想使用 vim 的替换命令或仅使用 sed 进行快速编辑。问题是我基本上没有实现与我想要替换为“无”的路径相匹配。

实际文件更大,我将只粘贴其中的一部分,但我认为它有很多这样的行:

Category.php">category.php
Copyright.php">Copyright.php
Core.php">Core.php
Credit.php">Credit.php

所以问题是,我想删除该">category.php部分,因为我不需要它,因此,我得到了这个正则表达式:

\">[A-z]+\.php[ ]+// 因此,如果它有一些空格,我会添加基本上带有空格的字符类。我还转义了第一个双引号,以防万一它会造成一些麻烦,但没有成功,vim 和 sed 都不会删除该部分。

我运行的实际命令是:

sed "s/\">[A-z]+.php//g":%s/\">[A-z]+.php//g在 vim 中。

答案1

使用以 " 作为分隔符的 cut 命令:

cut -d\" -f1 input-file

答案2

在 sed 和 vim 中,你的正则表达式都犯了一些错误。其他人给出了一些很好的替代方案,但我想解决为什么您给出的命令不起作用以及如何修复它们。

塞德

您的命令:sed "s/\">[A-z]+.php//g"

首先,你的字符类应该有一个有效的结尾,在这种情况下你可能想写[a-zA-Z].

其次,+运营商的一个特点是扩展正则表达式(ERE),默认情况下不启用这些。要启用它,请使用 和-E//标志-r--regexp-extended

您可以这样做,也可以在运算符前面加上反斜杠,例如\+.

更正的命令: sed 's/\">[a-zA-Z]\+.php//g'

维姆

您的命令::%s/\">[A-z]+.php//g

同样,你的角色类别是错误的。[a-zA-Z]如果您的搜索不区分大小写,这可能并不重要。

根据vim手册+运算符还应该以反斜杠为前缀,以便按您的预期工作。

更正的命令: :%s/\">[a-zA-Z]\+.php//g


笔记:

  • 在 sed 中,如果您使用 ERE,则可以\w使用[a-zA-Z]
  • 在 vim 中,你可以\a使用[a-zA-Z]

答案3

您可能不需要深入研究正则表达式,示例awk脚本可以完成这项工作:

awk -F\" '{print $1}' input_file

用作"分隔符并仅打印第一个标记。

答案4

假设您正在使用一些 XML 文档,例如

<?xml version="1.0"?>
<root>
  <node attr="Category.php">category.php</node>
  <node attr="Copyright.php">Copyright.php</node>
  <node attr="Core.php">Core.php</node>
  <node attr="Credit.php">Credit.php</node>
</root>

...并假设您要删除具有value 属性node的任何节点的值。您可以像这样使用:attrCategory.phpxmlstarlet

xmlstarlet edit --update '//node[@attr="Category.php"]' --value '' file.xml

或者,使用更短的语法,

xmlstarlet ed -u '//node[@attr="Category.php"]' -v '' file.xml

该字符串//node[@attr="Category.php"]是一个 XPath 查询,它node与文档中任意位置的节点集相匹配,其属性attr为 value Category.php

这会生成

<?xml version="1.0"?>
<root>
  <node attr="Category.php"/>
  <node attr="Copyright.php">Copyright.php</node>
  <node attr="Core.php">Core.php</node>
  <node attr="Credit.php">Credit.php</node>
</root>

在 Vim 编辑器中,您可以使用

:%!xmlstarlet ed -u '//node[@attr="Category.php"]' -v ''

如果要删除整个匹配节点(而不仅仅是其值),请使用

xmlstarlet edit --delete '//node[@attr="Category.php"]'

或者

xmlstarlet ed -d '//node[@attr="Category.php"]'

而不是xmlstarlet上面的命令。

相关内容