Ich habe diese Art von Zeilen in meinen Konfigurationsdateien,
bindsym $mod+F2 exec gnome-terminal #Open terminal bindsym $mod+p exec command /some/path" #Popup Dictionary bindsym $mod+Mod1+l exec --no-startup-id /some/path/command #Dmenu for my books collection bindsym Mod1+Control+b exec rxvt -e nnn #nnn file browser
Ich möchte awk
die zweite Spalte und Dinge nach #
löschen. Ich verwende awk
als
awk "/bindsym/{print $2}" filename
Ich bin mir jedoch nicht sicher, wie ich den Text nach der #
.
Die bevorzugte Ausgabe sind die Schlüssel und dann der Kommentartext als
$mod+F2 Open terminal
Antwort
$ awk -v OFS="\t" "/^bindsym/ { key = $2; sub(".*#", ""); print key, $0 }" file $mod+F2 Open terminal $mod+p Popup Dictionary $mod+Mod1+l Dmenu for my books collection Mod1+Control+b nnn file browser
Hiermit wird awk
verwendet, um zuerst das zweite Feld in jeder Zeile zu extrahieren beginnend mit bindsym
in die Variable key
. Es löscht dann alles bis einschließlich #
in der Zeile und druckt key
und was von der Zeile mit einer Registerkarte als übrig bleibt Trennzeichen.
Alternative Ausgabeformatierung:
$ awk "/^bindsym/ { key = $2; sub(".*#", ""); printf("%-20s\t%-20s\n", key, $0) }" file $mod+F2 Open terminal $mod+p Popup Dictionary $mod+Mod1+l Dmenu for my books collection Mod1+Control+b nnn file browser
Die Logik ist dieselbe, aber die Ausgabe weist jedem der beiden Zeichen 20 Zeichen zu ( linksbündig) Felder und fügt eine Registerkarte dazwischen (für ein gutes Maß).
Antwort
Verwenden Sie die match()
Funktion von GNU awk
, um den Teil von #
bis zum Ende der Zeile
awk "/bindsym/ && match($0,/#(.+)$/,arr){print $2, arr[1]}" filep
Die Funktion match()
füllt das im dritten Argument angegebene Array mit dem übereinstimmenden Muster aus dem regulären Ausdruck im zweiten Argument .
unter POSIX awk
wird das dritte Argument von match()
nicht unterstützt , aber einige spezielle Variablen RSTART
und RLENGTH
, die den Start und die Länge der übereinstimmenden Gruppe markieren. Wir verwenden die Funktion substr()
in der aktuellen Zeile, um die übereinstimmende Zeichenfolge
awk "/bindsym/ && match($0,/#(.+)$/){print $2, substr($0,RSTART+1,RLENGTH)}" file
zu erhalten, um die Ausgabe hübsch auszudrucken Sie können entweder die Funktion printf()
wie in der anderen Antwort verwenden.
Antwort
Dies ist sehr einfach in sed
; Da Ihre Daten nicht wirklich feldorientiert sind, bietet Awk hier keinen großen Vorteil:
sed "s/^[^ ]* //;s/ .*#//" inputfile
Übersetzung:
s/^[^ ]* //
Löschen Sie alles bis einschließlich des ersten Leerzeichens.
s/ .*#//
Löschen Sie alles aus dem ersten (verbleibenden) Leerzeichen. bis zum letzten #
Zeichen in der Zeile.
Antwort
Step1: count=`awk "{print NR}"|sed -n "$p" filename` Step2:for ((i=1;i<=$count;i++)); do awk -v i="$i" "NR==i && $0 ~ /^bindsym/{print $2}" filename; sed -n ""$i"s/.*#//p" filename; done| sed "N;s/\n/ /g" output for ((i=1;i<=$count;i++)); do awk -v i="$i" "NR==i && $0 ~ /^bindsym/{print $2}" filename; sed -n ""$i"s/.*#//p" filename; done| sed "N;s/\n/ /g" $mod+F2 Open terminal $mod+p Popup Dictionary $mod+Mod1+l Dmenu for my books collection Mod1+Control+b nnn file browser
Kommentare
- Ich ' gehe davon aus, dass möglicherweise mehr als vier Zeilen vorhanden sind die Eingabedatei. Es ist nicht klar, was Ihr erster Schritt tun würde, außer die Zeilennummer im Terminal auszudrucken.
- Korrigieren des Codes
- Korrigieren des Codes