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