Usando awk para imprimir la segunda columna y el resto del texto de #

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

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *