Я получил список установленных программ на моем компьютере с Ubuntu с помощьюapt list --installed
Вот фрагмент списка
wdiff/xenial,now 1.2.2-1build1 amd64 [installed,automatic]
wget/xenial-updates,xenial-security,now 1.17.1-1ubuntu1.5 amd64 [installed]
whiptail/xenial,now 0.52.18-1ubuntu2 amd64 [installed]
xauth/xenial,now 1:1.0.9-1ubuntu2 amd64 [installed]
xdg-user-dirs/xenial-updates,now 0.15-2ubuntu6.16.04.1 amd64 [installed]
xfsprogs/xenial-updates,now 4.3.0+nmu1ubuntu1.1 amd64 [installed]
xkb-data/xenial,now 2.16-1ubuntu1 all [installed]
Мне нужно название программы и версия. Например:
wdiff/xenial,now 1.2.2-1build1 amd64 [installed,automatic]
становится
wdiff 1.2.2-1build1
Я придумал эту команду, которая работает.
apt list --installed | sed -r 's@/@ @g' | awk '{print $1 "\t" $3}' | sort -u
Я хотел бы узнать, как использовать только sed для создания нового файла с частями строки входного файла.
Это регулярное выражение:
^([^\/]+)\/[^\s]+\s([^\s]+)
- Захват от начала строки до первого /
- Игнорировать до первого пробела
- Захват после первого пробела до второго пробела
И я должен иметь возможность использовать обратные ссылки sed на группы захвата и создавать новый вывод.
apt list --installed | sed -r 's/^([^\/]+)\/[^\s]+\s([^\s]+)/\1 \2/'
Однако, похоже, результат не соответствует моим ожиданиям.
wdiff [installed,automatic]
wget/xenial-updates,xenial-security,now 1.17.1-1ubuntu1.5 amd64 [installed]
whiptail [installed]
xauth [installed]
xdg-user-dirs/xenial-updates,now 0.15-2ubuntu6.16.04.1 amd64 [installed]
xfsprogs/xenial-updates,now 4.3.0+nmu1ubuntu1.1 amd64 [installed]
xkb-data [installed]
Что не так?
решение1
Что не так? Вы захватили не ту группу и не сбросили до конца входной строки после последнего совпадения, которое вы хотели сохранить, а только до следующего непробельного символа
sed -r 's/^([^\/]+)\/[^\s]+\s([^\s]+)/\1 \2/'
([^/]+) #capture everything up to /, OK
/ #discard the /. OK
[^\s] #discard the next non white-space group, this is the bit you actually want
\s #discard the whitespace
([^\s]+) #capture the next non-whitespace group
#leave anything after the last non-whitespace found
Вы, вероятно, сделали это из-за плохой читаемости со всеми этими экранами. Если вы это почистите, это поможет вам отладить
sed -E 's|([^/]*)[^ ]* +([^ ]*).*|\1 \2|' infile | column -t
([^/]*) #capture up to the /
[^ ]* + #discard until the space and any spaces
([^ ]) #capture the next character group until a space
.* #discard to the end of the string
Если вы не указали глобальное соответствие ( s///g
), то якорь вам не нужен ^
.
Используйте |
в качестве разделителя, чтобы избежать ненужных экранированных символов в совпадающей строке.
Выполняет column -t
лучшую работу по выравниванию, чем несколько пробелов
решение2
Попробуйте следующее (неоптимизированное) регулярное выражение:
$ sed 's/\(^.*\)\(\/[^ ]* \)\([^ ]* \)\([^ ]* \)\([^ ]*\)/\1 \3/' infile
wdiff 1.2.2-1build1
wget 1.17.1-1ubuntu1.5
whiptail 0.52.18-1ubuntu2
xauth 1:1.0.9-1ubuntu2
xdg-user-dirs 0.15-2ubuntu6.16.04.1
xfsprogs 4.3.0+nmu1ubuntu1.1
xkb-data 2.16-1ubuntu1