![如何删除‘-’后的文字?](https://linux22.com/image/1001603/%E5%A6%82%E4%BD%95%E5%88%A0%E9%99%A4%E2%80%98-%E2%80%99%E5%90%8E%E7%9A%84%E6%96%87%E5%AD%97%EF%BC%9F.png)
我有一个文件列表(基本上它们是.deb
包)。假设:
abc-de-1.2.3-1.deb
fgh-ij-4.5.6-2.deb
klm-no-7.8.9-3.deb
pqrs-10.11.12-4.deb
...
如您所见,一些文件名后面有数字,-
而其他文件名后面有一些文本-
,然后下一个后面有数字-
。
有没有什么方法可以删除从数字开始的所有内容,包括-
,即
abc-de
fgh-ij
klm-no
pqrs
...
我想编辑列表,而不是重命名文件。
答案1
如果您每次能够使用第一个数字来识别要删除的内容,则可以使用:
$ sed 's/-[0-9].*//' file
abc-de
fgh-ij
klm-no
pqrs
笔记
s/old/new/
old
用。。。来代替new
[0-9]
一些数字.*
任意数量的任意字符
答案2
与 Perl 正则表达式一起使用grep
:
$ grep -Po "^[a-z-]*(?=-[0-9])" filename
abc-de
fgh-ij
klm-no
pqrs
答案3
Perl
$ perl -lne 's/([[:digit:]].*)//;s/-$//;print' input.txt
abc-de
fgh-ij
klm-no
pqrs
这将执行两次替换,一次删除以数字开头的所有内容,一次删除尾随的-
。另外使用-i
选项编辑原始文件,例如$ perl -i -lne 's/([[:digit:]].*)//;s/-$//;print' input.txt
或者,使用贪婪的非数字匹配和分组:
$ perl -lne 's/^(\D*)-.*/\1/;print' input.txt
abc-de
fgh-ij
klm-no
pqrs
大王
$ awk -F '-' '{s=$1;for(i=2;i<=NF;i++) if($i~/[0-9].*/){print s;next}else{s=s"-"$i}}' input.txt
abc-de
fgh-ij
klm-no
pqrs
其工作原理是,我们将其视为-
字段的分隔符,然后遍历每一行。我们“缓存”第一个字段,然后使用for
循环继续迭代。在每次迭代中,我们都会检查列中是否不包含数字,并将其填充到s
变量中。如果列包含数字 - 我们会打印保存的内容并转到下一行。
> new_file.txt
在最后使用将输出重定向到新文件。
Python
#!/usr/bin/env python
import sys,re
with open(sys.argv[1]) as f:
for line in f:
tokens = re.split("-|\.",line.strip().replace(".deb",""))
words_only = filter(lambda x: not x.isdigit(),tokens)
print("-".join(words_only))
我们将re.split()
每一行分解为标记列表,并仅过滤非数字标记。
或者,这里有一个单行命令。如果行中没有数字,则不会采取预防措施,因此仅当您确定所有行都包含数字时才使用此命令。
$ python -c 'import re,sys;f=open(sys.argv[1]);print("\n".join([ l[:re.search(r"\d",l).start()-1] for l in f]))' input.txt
包名称中可能包含的数字
hvd 在评论中正确地指出,有时包名称中可能包含整数,这可能会给解析输入文件带来困难,而版本名称中通常包含点。考虑到这一点,可以稍微修改命令以解决这个问题:
$ perl -lne 's/\d*\..*//;s/-$//;print' input.txt
$ awk '{gsub(/[0-9]*\..*/,"");print substr($0,0,length($0)-1)};' input.txt
$ python -c 'import re,sys;f=open(sys.argv[1]);print("\n".join([ l[:re.search(r"\d*\.",l).start()-1] for l in f]))' input.txt
答案4
我猜测一下,既然你建议这些文件是 DEB 包,那么也许你想要类似这样的东西:
dpkg-query -f '${Package}\n' -W 'gnome*'
其中,gnome*
您可以用任何模式代替 。我不确定 DEB 档案的命名惯例究竟是什么,但如果它们是 DEB 档案,那么最好依靠 来dpkg
为您提供软件包名称。
如果这些是 DEB 存档文件(在您的系统上),那么您可以使用:
dpkg-deb --showformat='${Package}\n' -W some-file.deb