Mam takie linie w swoich plikach konfiguracyjnych,
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
Chcę awk
usunąć drugą kolumnę i elementy po #
. Używam awk
as
awk "/bindsym/{print $2}" filename
Nie jestem pewien, jak uzyskać tekst po #
.
Preferowane wyjście to klucze, a następnie tekst komentarza jako
$mod+F2 Open terminal
Odpowiedź
$ 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
W tym celu awk
najpierw wyodrębnia drugie pole w każdym wierszu zaczynając od bindsym
do zmiennej key
. Następnie usuwa wszystko, aż do #
włącznie, w wierszu i drukuje key
oraz to, co pozostało z wiersza z tabulatorem jako separator.
Alternatywne formatowanie wyjściowe:
$ 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 jest taka sama, ale na wyjściu przydziela się 20 znaków dla każdego z dwóch ( wyrównane do lewej) i umieszcza pomiędzy nimi tabulator (dla dokładności).
Odpowiedź
Używając match()
funkcja GNU awk
w celu dopasowania części od #
do końca wiersza
awk "/bindsym/ && match($0,/#(.+)$/,arr){print $2, arr[1]}" filep
Funkcja match()
wypełnia tablicę podaną w trzecim argumencie dopasowanym wzorcem z wyrażenia regularnego w drugim argumencie .
w każdym POSIX awk
trzeci argument match()
nie jest obsługiwany , ale kilka specjalnych zmiennych RSTART
i RLENGTH
, które oznaczają początek i długość dopasowanej grupy. Używamy funkcji substr()
w bieżącym wierszu, aby uzyskać dopasowany ciąg
awk "/bindsym/ && match($0,/#(.+)$/){print $2, substr($0,RSTART+1,RLENGTH)}" file
Aby ładnie wydrukować wynik , możesz użyć funkcji printf()
tak jak w drugiej odpowiedzi.
Odpowiedź
Jest to bardzo proste w sed
; ponieważ Twoje dane nie są tak naprawdę zorientowane na pola, awk nie zapewnia tutaj ogromnych korzyści:
sed "s/^[^ ]* //;s/ .*#//" inputfile
Tłumaczenie:
s/^[^ ]* //
Usuń wszystko do pierwszego znaku spacji włącznie.
s/ .*#//
Usuń wszystko od pierwszego (pozostałego) znaku spacji, aż do ostatniego #
znaku w wierszu.
Odpowiedź
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
Komentarze
- I ' m zakładając, że mogą być więcej niż cztery wiersze plik wejściowy. Nie jest jasne, jaki byłby twój pierwszy krok poza wydrukowaniem numeru linii w terminalu.
- Poprawianie kodu
- Poprawienie kodu