af te drukken, ik heb dit soort regels in mijn configuratiebestanden,
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
Ik wil awk
de tweede kolom verwijderen en dingen die na de #
staan. Ik gebruik awk
als
awk "/bindsym/{print $2}" filename
Ik weet niet zeker hoe ik de tekst na de #
.
De voorkeursuitvoer is, de sleutels en vervolgens de commentaartekst als
$mod+F2 Open terminal
Antwoord
$ 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
Dit gebruikt awk
om eerst het tweede veld op elke regel te extraheren te beginnen met bindsym
in de variabele key
. Vervolgens wordt alles verwijderd tot en met de #
op de regel en wordt key
afgedrukt en wat er nog over is van de regel met een tab als scheidingsteken.
Alternatieve outputformattering:
$ 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
De logica is hetzelfde, maar de output kent 20 karakters toe voor elk van de twee ( links uitgelijnd) velden en plaatst er een tab tussen (voor een goede meting).
Antwoord
Met behulp van de match()
functie van GNU awk
om het deel van #
tot het einde van de regel
awk "/bindsym/ && match($0,/#(.+)$/,arr){print $2, arr[1]}" filep
De functie match()
vult de array in het derde argument met het overeenkomende patroon van de regex in het tweede argument .
op elk POSIX awk
, wordt het derde argument van match()
niet ondersteund , maar een paar speciale variabelen RSTART
en RLENGTH
die de start en de lengte van de overeenkomende groep markeren. We gebruiken de substr()
functie op de huidige regel om de overeenkomende string te krijgen
awk "/bindsym/ && match($0,/#(.+)$/){print $2, substr($0,RSTART+1,RLENGTH)}" file
Om de uitvoer mooi af te drukken , je kunt ofwel de printf()
-functie gebruiken zoals in het andere antwoord.
Answer
Dit is heel eenvoudig te doen in sed
; aangezien uw gegevens niet echt veldgericht zijn, biedt Awk hier geen enorm voordeel:
sed "s/^[^ ]* //;s/ .*#//" inputfile
Vertaling:
s/^[^ ]* //
Verwijder alles tot en met het eerste spatie-teken.
s/ .*#//
Verwijder alles van het eerste (resterende) spatie-teken, tot het laatste #
teken op de regel.
Antwoord
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
Reacties
- Ik ' m ervan uitgaande dat er meer dan vier regels in het invoerbestand. Het is niet duidelijk wat uw eerste stap zou doen, behalve het regelnummer in de terminal afdrukken.
- De code corrigeren
- De code corrigeren