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