![陷入正则表达式语法困境](https://linux22.com/image/215050/%E9%99%B7%E5%85%A5%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F%E8%AF%AD%E6%B3%95%E5%9B%B0%E5%A2%83.png)
我正在编写一个基本的 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
的任何节点的值。您可以像这样使用:attr
Category.php
xmlstarlet
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
上面的命令。