Folosind awk pentru a imprima a doua coloană și restul textului din #

Am acest gen de linii în fișierele mele de configurare,

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 

Vreau să awk să scot a doua coloană și lucrurile care se află după #. Folosesc awk ca

awk "/bindsym/{print $2}" filename 

Nu știu cum să obțin textul după #.
Ieșirea preferată este, tastele și apoi textul comentariului ca

$mod+F2 Open terminal 

Răspuns

$ 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 

Aceasta folosește awk pentru a extrage mai întâi al doilea câmp pe fiecare linie începând cu bindsym în variabila key. Apoi șterge totul până la și include # de pe linie și imprimă key și ce rămâne din linie cu o filă ca delimitator.

Formatare alternativă a ieșirilor:

$ 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 

Logica este aceeași, dar rezultatul alocă 20 de caractere pentru fiecare dintre cele două ( justificate la stânga) și pune o filă între ele (pentru o măsură bună).

Răspunde

Utilizând match() funcția GNU awk pentru a se potrivi cu partea de la # până la sfârșitul liniei

awk "/bindsym/ && match($0,/#(.+)$/,arr){print $2, arr[1]}" filep 

Funcția match() completează tabloul furnizat în al treilea argument cu modelul potrivit din regex în al doilea argument .

pe orice POSIX awk, al treilea argument al match() este nu acceptat , dar câteva variabile speciale RSTART și RLENGTH care marchează start și lungimea grupului potrivit. Folosim funcția substr() de pe linia curentă pentru a obține șirul potrivit

awk "/bindsym/ && match($0,/#(.+)$/){print $2, substr($0,RSTART+1,RLENGTH)}" file 

Pentru a imprima destul de bine ieșirea , puteți folosi funcția printf() ca în celălalt răspuns.

Răspuns

Acest lucru este foarte simplu de făcut în sed; deoarece datele dvs. nu sunt într-adevăr Awk orientate pe câmp nu oferă un avantaj imens aici:

sed "s/^[^ ]* //;s/ .*#//" inputfile 

Traducere:

s/^[^ ]* // 

Ștergeți totul până la primul caracter spațial inclusiv.

s/ .*#// 

Ștergeți totul din primul caracter spațial (rămas), până la ultimul # caracter de pe linie.

Răspuns

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 

Comentarii

  • Am ' presupunând că pot exista mai mult de patru linii în fișierul de intrare. Nu este clar ce ar face primul dvs. pas decât să tipăriți numărul liniei din terminal.
  • Corectarea codului
  • Corectarea codului

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *