Utiliser awk pour imprimer la 2e colonne et le reste du texte de #

Jai ce genre de lignes dans mes fichiers de configuration,

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 

Je souhaite awk sortir la deuxième colonne et les éléments qui se trouvent après #. Jutilise awk comme

awk "/bindsym/{print $2}" filename 

Je ne sais pas trop comment obtenir le texte après #.
La sortie préférée est, les clés puis le texte du commentaire comme

$mod+F2 Open terminal 

Réponse

$ 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 

Cela utilise awk pour extraire dabord le deuxième champ de chaque ligne commençant par bindsym dans la variable key. Il supprime ensuite tout jusquà et y compris le # sur la ligne et imprime key et ce qui reste de la ligne avec un onglet délimiteur.

Autre formatage de sortie:

$ 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 

La logique est la même, mais la sortie alloue 20 caractères pour chacun des deux ( justifié à gauche) et met une tabulation entre eux (pour faire bonne mesure).

Réponse

En utilisant le match() fonction de GNU awk pour faire correspondre la partie de # jusquà la fin de la ligne

awk "/bindsym/ && match($0,/#(.+)$/,arr){print $2, arr[1]}" filep 

La fonction match() remplit le tableau fourni dans le troisième argument avec le modèle correspondant de lexpression régulière dans le deuxième argument .

sur nimporte quel POSIX awk, le troisième argument de match() nest pas pris en charge , mais deux variables spéciales RSTART et RLENGTH qui marquent le début et la longueur du groupe correspondant. Nous utilisons la fonction substr() sur la ligne en cours pour obtenir la chaîne correspondante

awk "/bindsym/ && match($0,/#(.+)$/){print $2, substr($0,RSTART+1,RLENGTH)}" file 

Pour afficher la sortie , vous pouvez utiliser la fonction printf() comme dans lautre réponse.

Réponse

Cest très simple à faire dans sed; puisque vos données ne sont pas vraiment orientées champ, Awk ne fournit pas un énorme avantage ici:

sed "s/^[^ ]* //;s/ .*#//" inputfile 

Traduction:

s/^[^ ]* // 

Tout supprimer jusquau premier caractère despace inclus.

s/ .*#// 

Tout supprimer du premier caractère despace (restant), jusquau dernier # caractère de la ligne.

Réponse

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 

Commentaires

  • I ' m en supposant quil peut y avoir plus de quatre lignes dans le fichier dentrée. Ce que votre première étape ferait autre que dimprimer le numéro de ligne dans le terminal nest pas clair.
  • Correction du code
  • Correction du code

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *