Utilizzo di awk per stampare la seconda colonna e il resto del testo da #

Ho questo tipo di righe nei miei file di configurazione,

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 

Voglio awk la seconda colonna e le cose che sono dopo #. Utilizzo awk come

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

Non sono sicuro di come ottenere il testo dopo #.
Loutput preferito è, le chiavi e quindi il testo del commento come

$mod+F2 Open terminal 

Risposta

$ 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 

Utilizza awk per estrarre prima il secondo campo su ogni riga iniziando con bindsym nella variabile key. Quindi elimina tutto fino al # incluso nella riga e stampa key e ciò che resta della riga con una tabulazione come delimitatore.

Formattazione di output alternativa:

$ 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 

La logica è la stessa, ma loutput alloca 20 caratteri per ciascuno dei due ( giustificato a sinistra) e inserisce una tabulazione tra di essi (per buona misura).

Risposta

Utilizzando match() funzione di GNU awk per abbinare la parte da # fino alla fine della riga

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

La funzione match() popola larray fornito nel terzo argomento con il modello corrispondente dellespressione regolare nel secondo argomento .

su qualsiasi awk POSIX, il terzo argomento di match() non è supportato , ma un paio di variabili speciali RSTART e RLENGTH che contrassegnano l inizio e la lunghezza del gruppo corrispondente. Usiamo la funzione substr() sulla riga corrente per ottenere la stringa corrispondente

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

Per stampare in modo carino loutput , puoi utilizzare la funzione printf() come nellaltra risposta.

Risposta

È molto semplice da fare in sed; poiché i tuoi dati non sono realmente orientati al campo Awk non fornisce un enorme vantaggio qui:

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

Traduzione:

s/^[^ ]* // 

Elimina tutto fino al primo carattere spazio incluso.

s/ .*#// 

Elimina tutto dal primo carattere spazio (rimanente), fino allultimo # carattere sulla riga.

Risposta

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 

Commenti

  • I ' m presumo che ci possano essere più di quattro righe in il file di input. Non è chiaro cosa farebbe il tuo primo passaggio se non stampare il numero di riga nel terminale.
  • Correzione del codice
  • Correzione del codice

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *