Verwenden von awk zum Drucken der zweiten Spalte und des restlichen Textes aus #

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

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.