Como deletar uma linha com busca variável usando o comando sed

2

O que há de errado com o comando sed ao excluir a linha que corresponde aos dados de entrada?

InputData.txt

123,
1234,
1453,

Datatodelete.txt

1234,hellofirstline
123,hellosecondline
14676,hellothirdline
1453,hellofourthline

saída esperada no Datatodelete.txt

14676,hellothirdline

Script:

echo "the script starts now"
while read EachLine
do
  echo $EachLine
  sed "/$EachLine/d" < /home/Datatodelete.txt >/home/dummy
done < /home/InputData.txt
    
por user3438085 19.03.2014 / 16:06

3 respostas

5

Seu comando sed não funciona porque, durante o loop, cada vez que ele lê uma linha, ele exclui essa linha (e somente essa linha) do arquivo de entrada completo, enviando-a para /home/dummy . Isso significa que o arquivo de saída é sobrescrito a cada vez. Portanto, a primeira iteração do loop remove a linha que começa com 123, , mas a segunda iteração usa o arquivo original completo que ainda inclui essa linha.

Experimente grep :

grep -vFf /home/InputData.txt /home/Datatodelete.txt > /home/dummy

De man grep :

   -F, --fixed-strings
          Interpret PATTERN as a  list  of  fixed  strings,  separated  by
          newlines,  any  of  which is to be matched.  (-F is specified by
          POSIX.)

   -f FILE, --file=FILE
          Obtain  patterns  from  FILE,  one  per  line.   The  empty file
          contains zero patterns, and therefore matches nothing.   (-f  is
          specified by POSIX.)
   -v, --invert-match
          Invert the sense of matching, to select non-matching lines.  (-v
          is specified by POSIX.)
    
por 19.03.2014 / 16:12
2

Uma versão awk :

awk -F, 'FNR==NR{a[$1];next} !($1 in a)' InputData.txt Datatodelete.txt
    
por 19.03.2014 / 16:20
1

Primeiro, você não quer while read lá em qualquer lugar - sed lerá seu arquivo. Em seguida, você precisa ter certeza de que você lida com greedy correspondências - sed irá puxar o máximo que puder. Então

    echo 1234 | sed -n '/123/p' 
1234

Veja? Ele imprime.

Então você precisa, com base no que você mostrou, algo assim:

    </home/InputData.txt \
        sed -n '/1234/s//& hellofirstline/p;\
        /123[^4]/s//& hellosecondline/p;\
        /14676/s//& hellothirdline/p;\ 
        /1453/s//& hellofourthline/p' >/home/dummy

Se o seu script sed estiver em um arquivo:

    </home/InputData.txt \
        sed -nf ./delete.sed >/home/dummy         
    
por 19.03.2014 / 16:14