Brug awk til at udskrive 2. kolonne og resten af teksten fra #

Jeg har denne slags linjer i mine konfigurationsfiler,

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 

Jeg vil awk ud af den anden kolonne og ting, der er efter #. Jeg bruger awk som

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

Jeg er dog ikke sikker på, hvordan jeg får teksten efter #.
Det foretrukne output er tasterne og derefter kommentarteksten som

$mod+F2 Open terminal 

Svar

$ 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 

Dette bruger awk til først at udtrække det andet felt på hver linje startende med bindsym i variablen key. Derefter slettes alt til og med # på linjen og udskriver key og hvad der er tilbage af linjen med en fane som afgrænser.

Alternativ outputformatering:

$ 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 

Logikken er den samme, men output tildeler 20 tegn til hver af de to ( venstrejusterede) felter og sætter en fane imellem dem (for godt mål).

Svar

Brug af match() funktion af GNU awk for at matche delen fra # til slutningen af linjen

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

match() -funktionen udfylder arrayet i det tredje argument med det matchede mønster fra regex i det andet argument .

på ethvert POSIX awk understøttes det tredje argument for match() ikke , men et par specielle variabler RSTART og RLENGTH som markerer start og længden for den matchede gruppe. Vi bruger substr() -funktionen på den aktuelle linje for at få den matchede streng

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

For at udskrive output , kan du enten bruge printf() -funktionen som i det andet svar.

Svar

Dette er meget simpelt at gøre i sed; da dine data ikke er rigtigt feltorienterede, giver Awk ikke en stor fordel her:

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

Oversættelse:

s/^[^ ]* // 

Slet alt til og med det første mellemrumstegn.

s/ .*#// 

Slet alt fra det første (resterende) mellemrumstegn, op til det sidste # tegn på linjen.

Svar

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 

Kommentarer

  • I ' m forudsat at der kan være mere end fire linjer i inputfilen. Det er ikke klart, hvad dit første trin ville gøre andet end at udskrive linjenummeret i terminalen.
  • Korrektion af koden
  • Korrigeret koden

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *