Exclua a enésima linha de uma string combinada (que ocorre apenas uma vez no arquivo)

1

Eu tenho uma pergunta relacionada à exclusão de sequências que aparecem na n+2 position após a string correspondente que está na posição n usando awk para vários arquivos. Eu posso imprimir usando o comando:

 awk -F '/radius-server/{nr[NR+4]}; NR in nr' *

Onde a string correspondente é radius-server . Desde que eu não estou muito familiarizado com awk Eu apreciaria se alguém pudesse me ajudar a excluir esta linha, , isso significaria que eu quero que os arquivos sejam modificados e salvos após a exclusão ser feita. Um cenário de exemplo está abaixo - file 1 , que não foi modificado

 radius-server dz7HQQH4EqT5 1645-1646
 !
 oj5icqh1dGpSK
 !  
 alias exec t telnet
 alias exec sis show interface status
 !

file 2 , após a modificação ser -

radius-server dz7HQQH4EqT5 1645-1646
!
!
alias exec t telnet
alias exec sis show interface status
!

Entendo que posso fazer um método de correspondência de padrão usando sed -i '/pattern/d' para removê-lo, mas não é isso que quero, pois os valores mudam de arquivo para arquivo. Qualquer ajuda seria muito apreciada.

    
por Zzrot 30.04.2016 / 19:15

3 respostas

1

sed parece ser a ferramenta certa:

sed -i '/radius-server/!b;n;n;d' filename

Como funciona:

/radius-server/!b # as long as it's NOT 'radius-server' do nothing (branch to end)
n # read next line (replace current line with next line)
n # same as above - we now read 2 lines
d # delete the current line

UPDATE - para modificar vários arquivos, basta usar glob em vez de filename, por exemplo,

sed -i '/radius-server/!b;n;n;d' *
    
por 30.04.2016 / 21:30
0

A menos que você tenha o GNU awk 4.1.0 ou posterior ...

Você não terá essa opção como a opção -i do sed, então faça:

for file in *
do
awk -v lines=2 'BEGIN { ignore = -1 } /radius-server/ { ignore = NR + lines } NR != ignore { print }' "$file"
done > result.txt

Isso funciona da seguinte maneira:

BEGIN { ignore = -1 }             # initialize ignore with -1 so NR will never
                                  # be equal to it by accident

/radius-server/ { ignore = NR + lines } # when the radius-server is found, set ignore to the
                                  # line we want to ignore

NR != ignore { print }            # unless the current line is that line, print
                                  # it.

Nota: o -i não é mágico, ele também está criando um arquivo temporário sed apenas o manipula para você.

Atualizar

Se você precisar recorrer aos subdiretórios:

find . -type f -exec awk ... {} ; > result.txt

Em ambos os casos, você provavelmente deve colocar o resultado.txt em um diretório diferente. Caso contrário, ele será correspondido e usado como um arquivo de entrada.

    
por 30.04.2016 / 19:44
0
PATH_TO_FOLDER="/some/path/to/folder/"
FILE_EXTENSION=".ext"
FILES=$(ls ${PATH_TO_FOLDER}/*${FILE_EXTENSION})

for FILE in $FILES; do
FILENAME=$(basename $FILE ${FILE_EXTENSION})
TMP_FILE=${PATH_TO_FOLDER}/${FILENAME}.tmp
awk -v Lines=2 '{if($0~"radius-server"){ 
print;
for(i=0;i<=Lines;i++)
{
getline;
if(i==Lines){
next;
}else{
print; 
}
} 
}
else{
print;
}
}' $FILE > $TMP_FILE
mv ${TMP_FILE} ${FILE}

Em princípio, isso deve funcionar. Basicamente, se a linha contém radius-server, essa linha será impressa e, em seguida, iterará pelas próximas 3 linhas. 0 imprimirá a primeira linha, 1 imprimirá a segunda linha e, em seguida, 3 saltará a terceira linha. Para todos os outros casos, as linhas são impressas como estão.

    
por 01.05.2016 / 14:09