Obtuve una lista de programas instalados en mi Ubuntu Box usandoapt list --installed
Aquí hay un fragmento de la 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]
Necesito el nombre y la versión del programa. Por ejemplo:
wdiff/xenial,now 1.2.2-1build1 amd64 [installed,automatic]
se convierte
wdiff 1.2.2-1build1
Ideé este comando que funciona.
apt list --installed | sed -r 's@/@ @g' | awk '{print $1 "\t" $3}' | sort -u
Me gustaría saber cómo usar solo sed para crear un archivo nuevo con partes de la línea del archivo de entrada.
Esta expresión regular:
^([^\/]+)\/[^\s]+\s([^\s]+)
- Captura desde el inicio de la línea hasta la primera /
- Ignorar hasta el primer espacio en blanco.
- Capturar después del primer espacio en blanco al segundo espacio en blanco
Y debería poder utilizar referencias inversas de sed a los grupos de captura y crear el nuevo resultado.
apt list --installed | sed -r 's/^([^\/]+)\/[^\s]+\s([^\s]+)/\1 \2/'
Sin embargo, parece que el resultado no coincide con mis expectativas.
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]
¿Qué está pasando mal?
Respuesta1
¿Qué está pasando mal? Capturó el grupo equivocado y no lo descartó hasta el final de la cadena de entrada después de la última coincidencia que deseaba conservar, solo hasta el siguiente sin espacio en blanco.
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
Probablemente terminaste haciendo esto debido a la mala legibilidad de todos los escapes. Si lo limpias te ayudará 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 haya especificado una coincidencia global ( s///g
), no necesita el ^
ancla.
Úselo |
como separador para evitar escapes innecesarios en su cadena coincidente
Hace column -t
un mejor trabajo de alineación que los espacios múltiples.
Respuesta2
Pruebe la siguiente expresión regular (no optimizada):
$ 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