Awk gebruiken om de 2e kolom en de rest van de tekst van #

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

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *