Eu recebi uma lista de programas instalados na minha caixa do Ubuntu usandoapt list --installed
Aqui está um trecho da lista
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]
Preciso do nome e da versão do programa. Por exemplo:
wdiff/xenial,now 1.2.2-1build1 amd64 [installed,automatic]
torna-se
wdiff 1.2.2-1build1
Eu criei este comando que funciona.
apt list --installed | sed -r 's@/@ @g' | awk '{print $1 "\t" $3}' | sort -u
Gostaria de saber como usar apenas o sed para criar um novo arquivo com partes da linha do arquivo de entrada.
Esta regex:
^([^\/]+)\/[^\s]+\s([^\s]+)
- Captura do início da linha até o primeiro /
- Ignorar para o primeiro espaço em branco
- Capture após o primeiro espaço em branco para o segundo espaço em branco
E eu deveria ser capaz de usar referências anteriores do sed para os grupos de captura e construir a nova saída.
apt list --installed | sed -r 's/^([^\/]+)\/[^\s]+\s([^\s]+)/\1 \2/'
No entanto, parece que a saída não corresponde à minha expectativa.
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]
O que está errado?
Responder1
O que está errado? Você capturou o grupo errado e não descartou até o final da string de entrada após a última correspondência que queria manter, apenas até o próximo não-espaço em branco
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
Você provavelmente acabou fazendo isso por causa da baixa legibilidade de todas as fugas. Se você limpar, isso o ajudará a depurar
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
A menos que você tenha especificado uma correspondência global ( s///g
), você não precisa da ^
âncora.
Use |
como separador para evitar escapes desnecessários na string correspondente
O column -t
faz um trabalho de alinhamento melhor do que vários espaços
Responder2
Tente o seguinte regex (não otimizado):
$ 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