Ich habe eine Liste der installierten Programme auf meiner Ubuntu-Box mitapt list --installed
Hier ist ein Ausschnitt der Liste
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]
Ich brauche den Programmnamen und die Version. Beispiel:
wdiff/xenial,now 1.2.2-1build1 amd64 [installed,automatic]
wird
wdiff 1.2.2-1build1
Ich habe diesen Befehl entwickelt, der funktioniert.
apt list --installed | sed -r 's@/@ @g' | awk '{print $1 "\t" $3}' | sort -u
Ich möchte wissen, wie ich nur sed verwende, um eine neue Datei mit Teilen der Eingabedateizeile zu erstellen.
Dieser reguläre Ausdruck:
^([^\/]+)\/[^\s]+\s([^\s]+)
- Erfassen vom Zeilenanfang bis zum ersten /
- Ignorieren Sie das erste Leerzeichen
- Erfassen Sie nach dem ersten Leerzeichen bis zum zweiten Leerzeichen
Und ich sollte in der Lage sein, Sed-Rückverweise auf die Erfassungsgruppen zu verwenden und die neue Ausgabe zu erstellen.
apt list --installed | sed -r 's/^([^\/]+)\/[^\s]+\s([^\s]+)/\1 \2/'
Allerdings scheint das Ergebnis nicht meinen Erwartungen zu entsprechen.
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]
Was läuft schief?
Antwort1
Was läuft falsch? Sie haben die falsche Gruppe erfasst und nicht bis zum Ende der Eingabezeichenfolge nach der letzten Übereinstimmung, die Sie behalten wollten, verworfen, sondern nur bis zum nächsten Nicht-Leerzeichen.
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
Sie haben dies wahrscheinlich getan, weil die Lesbarkeit mit all den Escapezeichen schlecht war. Wenn Sie es bereinigen, hilft es Ihnen beim Debuggen
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
Sofern Sie keine globale Übereinstimmung ( s///g
) angegeben haben, benötigen Sie den ^
Anker nicht.
Verwenden Sie es |
als Trennzeichen, um unnötige Escapezeichen in Ihrer passenden Zeichenfolge zu vermeiden.
Dies column -t
ermöglicht eine bessere Ausrichtung als mehrere Leerzeichen.
Antwort2
Versuchen Sie den folgenden (nicht optimierten) regulären Ausdruck:
$ 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