Mám tyto typy řádků ve svých konfiguračních souborech,
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
Chci awk
vyjmout druhý sloupec a věci, které jsou za #
. Používám awk
as
awk "/bindsym/{print $2}" filename
Nejsem si však jistý, jak získat text po #
.
Upřednostňovaným výstupem jsou klíče a poté text komentáře jako
$mod+F2 Open terminal
odpověď
$ 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
Pomocí awk
se nejprve extrahuje druhé pole na každém řádku začínající bindsym
do proměnné key
. Poté odstraní vše až po #
na řádku a vytiskne key
a co zbývá z řádku se záložkou jako oddělovač.
Alternativní formátování výstupu:
$ 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
Logika je stejná, ale výstupu je pro každý z nich přiděleno 20 znaků ( pole zarovnaná vlevo) a umístí mezi ně záložku (pro správnou míru).
Odpovědět
Použití match()
funkce GNU awk
tak, aby odpovídala části od #
do konce řádku
awk "/bindsym/ && match($0,/#(.+)$/,arr){print $2, arr[1]}" filep
Funkce match()
naplní pole poskytnuté ve třetím argumentu odpovídajícím vzorem z regexu ve druhém argumentu .
na libovolném POSIX awk
není třetí argument match()
nepodporován , ale několik speciálních proměnných RSTART
a RLENGTH
, které označují začátek a délku shodné skupiny. K získání shodného řetězce používáme funkci substr()
na aktuálním řádku
awk "/bindsym/ && match($0,/#(.+)$/){print $2, substr($0,RSTART+1,RLENGTH)}" file
Chcete-li výstup pěkně vytisknout , můžete buď použít funkci printf()
jako v jiné odpovědi.
Odpověď
Toto je velmi jednoduché v sed
; protože vaše data opravdu nejsou orientovaná na pole Awk zde neposkytují obrovskou výhodu:
sed "s/^[^ ]* //;s/ .*#//" inputfile
Překlad:
s/^[^ ]* //
Smazat vše až po první znak mezery včetně.
s/ .*#//
Smazat vše od prvního (zbývajícího) znaku mezery, až po poslední #
znak na řádku.
Odpověď
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
Komentáře
- I ' m za předpokladu, že v řádku mohou být více než čtyři řádky vstupní soubor. Není jasné, co by udělal váš první krok, než vytisknout číslo řádku v terminálu.
- Oprava kódu
- Oprava kódu