我有一个名为foo.txt
. 该文件包含以下值:
abc.tar.gz
abc.1.1.tar.gz
bca-1.2.tar.gz
我想得到这样的输出
abc abc.tar.gz
abc.1.1 abc.1.1.tar.gz
bca-1.2 bca-1.2.tar.gz
相同的值/文本必须出现在原始值/文本之前。如何使用正则表达式实现这一点?
%s/^[a-z_-]*./\1/g
我使用了上面的表达式,但输出错误。
我有一个名为foo.txt
. 该文件包含以下值:
abc.tar.gz
abc.1.1.tar.gz
bca-1.2.tar.gz
我想得到这样的输出
abc abc.tar.gz
abc.1.1 abc.1.1.tar.gz
bca-1.2 bca-1.2.tar.gz
相同的值/文本必须出现在原始值/文本之前。如何使用正则表达式实现这一点?
%s/^[a-z_-]*./\1/g
我使用了上面的表达式,但输出错误。
捕获组
:help /\(
让你存储与模式匹配的内容\(...\)
;然后,您可以在替换中(甚至之后在模式本身中)引用匹配项(通过\1
第一组,\2
等等)。解决您的问题的一种方法(有很多)是在
.tar.gz
扩展名之前捕获文件名。在替换中,放置捕获 (\1
)、一个空格,然后是原始文本 (\0
, 或&
):或者,您可以只匹配扩展名之前的内容(以 结束匹配
\ze
),然后复制它:你的尝试有问题
\1
,但从未捕获任何内容。[a-z_-]
文字不匹配.
,但这出现在您的示例中。.
(as\.
);它会匹配任何字符。如果总是删除 .tar.gz,那么:
文件名:test
命令
输出
在当前接受的答案上旋转,如果字符串后缀可能从更改
.tar.gz
为其他.xxx.yyy
类似字符串,则以下将接受任何两个字符串xxx
和yyy
:这显然也可以用在
vi
as 中:%s/\(.*\)\(\..*\)\{2\}$/\1 &/
。或者,将扩展的正则表达式与
sed
可以理解的 a 一起使用-E
:{2}
此处表示匹配恰好两个以点分隔的子串的后缀。这不使用正则表达式,但从
.tar.gz
我假设的文件名中删除后缀,然后将原始数据粘贴为第二列。通过反转行然后保留从第 3 个字段开始的所有点分隔字段来删除后缀字符串。再次反转它具有切断最后两个以点分隔的文件名组件的效果。
最终输出以制表符分隔,但您可以通过将最后
paste
一步 替换为paste -d ' ' - foo.txt
.以与上述类似的方式,但使用
basename
实用程序切断.tar.gz
文件名后缀:一定要这样
vi
吗?如果没有,这可能会做你想做的(使用 GNU
xargs
)。foo.txt
你的文件在哪里。更新。
上面的你还不明白吗?