Как удалить текст после '-'?

У меня есть список файлов (в основном, они .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
...

Поскольку Вы видите, что некоторые имена файлов имеют числа после a - в то время как у других есть некоторый текст после a - и затем числа после следующего -.

Есть ли любые способы удалить все начинающее с чисел включая -, т.е.

abc-de
fgh-ij
klm-no
pqrs
...

Я хочу отредактировать список, не переименовывают файлы.

6
задан 23 July 2017 в 00:04

5 ответов

Если Вы можете использовать первое число для идентификации то, что Вы хотите удалить каждый раз, когда Вы могли использовать:

$ sed 's/-[0-9].*//' file
abc-de
fgh-ij
klm-no
pqrs

Примечания

  • s/old/new/ замена old с new
  • [0-9] некоторая цифра
  • .* любое количество любых символов
8
ответ дан 23 November 2019 в 07:16

Используя grep с регулярными выражениями Perl:

$ grep -Po "^[a-z-]*(?=-[0-9])" filename
abc-de
fgh-ij
klm-no
pqrs
6
ответ дан 23 November 2019 в 07:16

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

$ 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
ответ дан 23 November 2019 в 07:16

Через awk,

awk -F'-[0-9]' '{print $1}' file

В awk мы можем также передать regex как аргумент Разделителю полей -F. Таким образом, это разделило бы каждую строку на части, где regex соответствует.

Пример:

$ echo 'abc-de-1.2.3-1.deb' | awk -F'-[0-9]' '{print $1}'
abc-de
4
ответ дан 23 November 2019 в 07:16

Я выскажу предположение, так как Вы предположили, что файлы являются пакетами DEB, затем, возможно, Вы хотели что-то как:

dpkg-query -f '${Package}\n' -W 'gnome*'

Где, вместо gnome*, Вы могли заменить любым шаблоном. Я не уверен, что точно конвенция для именования архивов DEB, но если это - архивы DEB, вероятно, лучше полагаться dpkg дать Вам имя пакета.

И если это - архивные файлы DEB (в Вашей системе), то Вы могли использовать:

dpkg-deb --showformat='${Package}\n' -W some-file.deb 
1
ответ дан 23 November 2019 в 07:16

Другие вопросы по тегам:

Похожие вопросы: