Apagar números de linha específicos (passados como variáveis) de um arquivo no linux

0

Eu tenho dois arquivos. Um tendo uma lista de linhas (que eu não preciso) diz Seqlist e outro arquivo de texto (do qual eu pretendo deletar as linhas correspondentes) digamos ContentFile

$cat Seqlist         

3
4
7
10
345
7000
67001
.....

Eu usei:

$ while read A; do sed -e "$((A)d" ContentFile; done < Seqlist >OUTPUT

mas estou apenas excluindo o número da terceira linha. As linhas de descanso não estão sendo excluídas.

    
por ruchika 16.06.2016 / 12:42

4 respostas

3

A adição de um d ao final de cada número no arquivo de número de linha o transforma em um script sed que exclui as linhas especificadas de sua entrada. Então é fácil:

$ sed -f lines_to_delete.sed file_with_lines.txt

O script sed pode ser criado assim:

$ sed -e 's/$/d/' file_with_numbers.txt >lines_to_delete.sed
    
por 16.06.2016 / 12:52
1

Usando ed :

printf "%s\n" $(printf "%sd\n" $(sort -rnu Seqlist)) w | ed ContentFile

Isso usa printf para criar uma lista de comandos (comandos de exclusão de linha de uma lista única e reversa de números de linha da Seqlist e um "w" para gravar o arquivo modificado de volta no disco) para ed para usar para editar ContentFile

    
por 17.06.2016 / 07:52
0

Se a lista de linenumbers se encaixar na memória (mas não necessariamente no arquivo de conteúdo como ed ), você pode fazer

awk 'FNR==NR{n[$0];next} !(FNR in n)' Seqfile ContentFile

Se ambos os arquivos são (ou podem ser) enormes, e Seqfile é classificado

cat -n ContentFile | join -v2 -j1 Seqfile - | sed 's/^[0-9]* //'
    
por 17.06.2016 / 12:58
0

o problema é que o seu script executa o arquivo inteiro por sed na primeira passagem, de modo que nenhum dos outros números tenha efeito.

a maneira mais fácil de corrigir é criar uma lista de linhas e fazer uma única passagem pelo sed.

s=
while read a 
do s="$s$a d;"
done < Seqlist 
sed -e "$s" ContentFile  >OUTPUT
    
por 18.06.2016 / 11:32