Pergunta

Quero excluir um ou mais números de linha específicos de um arquivo. Como eu faria isso usando sed?

Foi útil?

Solução

Se você deseja excluir as linhas 5 a 10 e 12:

sed -e '5,10d;12d' file

Isso imprimirá os resultados na tela. Se você deseja salvar os resultados no mesmo arquivo:

sed -i.bak -e '5,10d;12d' file

Isso vai apoiar o arquivo até file.bak, e exclua as linhas dadas.

Nota: Os números de linha começam em 1. A primeira linha do arquivo é 1, não 0.

Outras dicas

Você pode excluir uma linha única específica com seu número de linha por arquivo sed -i '33d'

Isso excluirá a linha no número da linha 33 e salvará o arquivo atualizado.

e estranho também

awk 'NR!~/^(5|10|25)$/' file
$ cat foo
1
2
3
4
5
$ sed -e '2d;4d' foo
1
3
5
$ 

Isso geralmente é um sintoma de um antipulro. A ferramenta que produziu os números de linha pode muito bem ser substituída por uma que exclui as linhas imediatamente. Por exemplo;

grep -nh error logfile | cut -d: -f1 | deletelines logfile

(Onde deletelines é o utilitário que você está imaginando que precisa) é o mesmo que

grep -v error logfile

Dito isto, se você estiver em uma situação em que realmente precisa executar esta tarefa, pode gerar um simples sed script do arquivo de números de linha. Com humor (mas talvez um pouco confuso) você pode fazer isso com sed.

sed 's%$%d%' linenumbers

Isso aceita um arquivo de números de linha, um por linha, e produz, na saída padrão, os mesmos números de linha com d anexado após cada um. Este é um válido sed script, que podemos salvar em um arquivo, ou (em algumas plataformas) tubos para outro sed instância:

sed 's%$%d%' linenumbers | sed -f - logfile

Em algumas plataformas, sed -f não entende o argumento da opção - Para significar entrada padrão, para que você precise redirecionar o script para um arquivo temporário e limpá -lo quando terminar, ou talvez substituir o traço solitário por /dev/stdin ou /proc/$pid/fd/1 Se o seu sistema operacional (ou shell) tiver isso.

Como sempre, você pode adicionar -i antes de o -f opção para ter sed Edite o arquivo de destino, em vez de produzir o resultado na saída padrão. Em *plataformas BSDish (incluindo OSX), você precisa fornecer um argumento explícito para -i também; Um idioma comum é fornecer um argumento vazio; -i ''.

Gostaria de propor uma generalização com AWK.

Quando o arquivo é feito por blocos de tamanho fixo e as linhas a serem excluídas são repetidas para cada bloco, o AWK pode funcionar bem de tal maneira

awk '{nl=((NR-1)%2000)+1; if ( (nl<714) || ((nl>1025)&&(nl<1029)) ) print  $0}'
 OriginFile.dat > MyOutputCuttedFile.dat

Neste exemplo, o tamanho do bloco é de 2000 e eu quero imprimir as linhas [1..713] e [1026..1029].

  • NR é a variável usada pelo AWK para armazenar o número da linha atual.
  • % dá o restante (ou módulo) da divisão de dois números inteiros;
  • nl=((NR-1)%BLOCKSIZE)+1 Aqui escrevemos na variável nl o número da linha dentro do bloco atual. (Veja abaixo)
  • || e && são o operador lógico OU e E.
  • print $0 escreve a linha completa

Why ((NR-1)%BLOCKSIZE)+1:
(NR-1) We need a shift of one because 1%3=1, 2%3=2, but 3%3=0.
  +1   We add again 1 because we want to restore the desired order.

+-----+------+----------+------------+
| NR  | NR%3 | (NR-1)%3 | (NR-1)%3+1 |
+-----+------+----------+------------+
|  1  |  1   |    0     |     1      |
|  2  |  2   |    1     |     2      |
|  3  |  0   |    2     |     3      |
|  4  |  1   |    0     |     1      |
+-----+------+----------+------------+

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top