Jeg har denne typen linjer i konfigurasjonsfilene mine,
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
ut den andre kolonnen og ting som er etter #
. Jeg bruker awk
som
awk "/bindsym/{print $2}" filename
Jeg er ikke sikker på hvordan jeg får tak i teksten etter #
.
Den foretrukne utgangen er tastene og deretter 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 bruker awk
til å først trekke ut det andre feltet på hver linje starter med bindsym
inn i variabelen key
. Den sletter deretter alt til og med #
på linjen og skriver ut key
og hva som er igjen av linjen med en fane som skilletegn.
Alternativ utdataformatering:
$ 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 utdataene tildeler 20 tegn for hver av de to ( venstrejusterte) felt og setter en fane mellom dem (for godt mål).
Svar
Bruk match()
funksjon av GNU awk
for å matche delen fra #
til slutten av linjen
awk "/bindsym/ && match($0,/#(.+)$/,arr){print $2, arr[1]}" filep
match()
-funksjonen fyller matrisen i det tredje argumentet med det matchede mønsteret fra regex i det andre argumentet .
på ethvert POSIX awk
, støttes det tredje argumentet til match()
, men noen spesielle variabler RSTART
og RLENGTH
som markerer start og lengden for den samsvarende gruppen. Vi bruker substr()
-funksjonen på den nåværende linjen for å få den matchede strengen
awk "/bindsym/ && match($0,/#(.+)$/){print $2, substr($0,RSTART+1,RLENGTH)}" file
For å skrive ut utskriften pent , kan du enten bruke printf()
-funksjonen som i det andre svaret.
Svar
Dette er veldig enkelt å gjøre i sed
; siden dataene dine ikke er virkelig feltorienterte, gir Awk ikke en stor fordel her:
sed "s/^[^ ]* //;s/ .*#//" inputfile
Oversettelse:
s/^[^ ]* //
Slett alt til og med det første mellomromstegnet.
s/ .*#//
Slett alt fra det første (gjenværende) mellomromstegnet, opp til det siste #
tegnet 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
- Jeg ' Jeg antar at det kan være mer enn fire linjer i inngangsfilen. Det er ikke klart hva ditt første skritt ville gjort annet enn å skrive ut linjenummeret i terminalen.
- Korrigere koden
- Korrigert koden