Usando awk para imprimir a 2ª coluna e o resto do texto de #

Tenho esse tipo de linha em meus arquivos de configuração,

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 

Eu quero awk a segunda coluna e coisas que estão depois de #. Estou usando awk como

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

Não tenho certeza de como obter o texto após #.
A saída preferida é as chaves e o texto do comentário como

$mod+F2 Open terminal 

Resposta

$ 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 

Isso usa awk para primeiro extrair o segundo campo em cada linha começando com bindsym na variável key. Em seguida, ele exclui tudo até e incluindo # na linha e imprime key e o que resta da linha com uma guia como delimitador.

Formatação de saída alternativa:

$ 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 

A lógica é a mesma, mas a saída aloca 20 caracteres para cada um dos dois ( justificado à esquerda) e coloca uma tabulação entre eles (para uma boa medida).

Resposta

Usando o match() função do GNU awk para corresponder à parte de # até o final da linha

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

A função match() preenche a matriz fornecida no terceiro argumento com o padrão correspondente do regex no segundo argumento .

em qualquer POSIX awk, o terceiro argumento de match() não é compatível , mas algumas variáveis especiais RSTART e RLENGTH que marcam o início e o comprimento do grupo correspondido. Usamos a função substr() na linha atual para obter a string correspondente

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

Para imprimir a saída , você pode usar a função printf() como na outra resposta.

Resposta

Isso é muito simples de fazer em sed; já que seus dados não são realmente orientados para o campo, o Awk não fornece um grande benefício aqui:

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

Tradução:

s/^[^ ]* // 

Exclua tudo até e incluindo o primeiro caractere de espaço.

s/ .*#// 

Exclua tudo do primeiro (restante) caractere de espaço, até o último # caractere na linha.

Resposta

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 

Comentários

  • Eu ' estou supondo que pode haver mais de quatro linhas em o arquivo de entrada. Não está claro o que sua primeira etapa faria além de imprimir o número da linha no terminal.
  • Correção do código
  • Corrigido o código

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *