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