Tengo este tipo de líneas en mis archivos de configuración,
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
Quiero awk
salir de la segunda columna y las cosas que están después de #
. Estoy usando awk
como
awk "/bindsym/{print $2}" filename
Sin embargo, no estoy seguro de cómo obtener el texto después del #
.
La salida preferida es, las claves y luego el texto del comentario como
$mod+F2 Open terminal
Responder
$ 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
Esto usa awk
para extraer primero el segundo campo en cada línea comenzando con bindsym
en la variable key
. A continuación, elimina todo hasta el #
en la línea e incluye key
y lo que queda de la línea con una pestaña como delimitador.
Formato de salida alternativo:
$ 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 lógica es la misma, pero la salida asigna 20 caracteres para cada uno de los dos ( justificado a la izquierda) y coloca una pestaña entre ellos (por si acaso).
Respuesta
Usando el match()
función de GNU awk
para hacer coincidir la parte desde #
hasta el final de la línea
awk "/bindsym/ && match($0,/#(.+)$/,arr){print $2, arr[1]}" filep
La función match()
llena la matriz proporcionada en el tercer argumento con el patrón coincidente de la expresión regular en el segundo argumento .
en cualquier POSIX awk
, el tercer argumento de match()
no es compatible , pero un par de variables especiales RSTART
y RLENGTH
que marcan el inicio y la longitud del grupo emparejado. Usamos la función substr()
en la línea actual para obtener la cadena coincidente
awk "/bindsym/ && match($0,/#(.+)$/){print $2, substr($0,RSTART+1,RLENGTH)}" file
Para imprimir de forma bonita la salida , puede usar la función printf()
como en la otra respuesta.
Responder
Esto es muy simple de hacer en sed
; dado que sus datos no están realmente orientados al campo, Awk no proporciona un gran beneficio aquí:
sed "s/^[^ ]* //;s/ .*#//" inputfile
Traducción:
s/^[^ ]* //
Elimine todo hasta el primer carácter de espacio incluido.
s/ .*#//
Elimine todo desde el primer carácter de espacio (restante), hasta el último #
carácter de la línea.
Respuesta
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
Comentarios
- Yo ' m suponiendo que puede haber más de cuatro líneas en el archivo de entrada. No está claro qué haría su primer paso además de imprimir el número de línea en la terminal.
- Corregir el código
- Corregir el código