如何删除‘-’后的文字?

如何删除‘-’后的文字?

我有一个文件列表(基本上它们是.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 

相关内容