Como remover três feeds de linha consecutivos em uma regra Makefile?

2

Eu preciso procurar e substituir três caracteres de nova linha consecutivos em um arquivo de entrada e filtrá-los de um arquivo de saída para uma regra makefile no Centos 4. Estou usando o GNU sed v4.1.2 e o GNU make v3.82. Eu tentei variações sobre o seguinte sem sucesso até agora:

THREE_LINE_FEEDS := $(shell echo "222")

SED_RULE := 's/'$(THREE_LINE_FEEDS)'//'

output.txt: input.txt
    sed -r $(SED_RULE) input.txt > output.txt

Usando o perl proposto, recebo este problema no shell (adaptado da minha regra make):

> cat input.txt | perl -e '$/ = undef; _ = <>; s/\n{3}//g; print;' > output.txt
Can't modify constant item in scalar assignment at -e line 1, near "<>;"
Execution of -e aborted due to compilation errors.
    
por WilliamKF 28.07.2012 / 14:51

2 respostas

0

Para os interessados, aqui está a regra de makefile real (não consegui fazer as novas linhas funcionarem no original, então usei um comentário para adicionar a documentação):

# 0777  -  Enables slurp mode (i.e. $/ = undef;  -  Slurp mode, read whole file
#                                   $_ = <>;     -  Read file to $_)
# s/\n{3}//g;                                    -  Remove occurrences of \n{3}
# p     -  Implicitly print result (i.e. print;  -  Output $_)
output.txt: input.txt
    $(SED) -r $(SED_RULE) input.txt | perl -0777 -pe 's/\n{3}//g' > output.txt
    
por 28.07.2012 / 20:45
3

sed vê apenas uma linha por vez, portanto, a pesquisa por feeds de linha consecutivos não funcionará. Uma maneira é enviar todos os dados para o espaço de espera e, em seguida, substituir quando todas as entradas forem coletadas, por exemplo:

sed -r -n '
  $! {             # When it is not the last line
    1  { h }       # Replace hold space with first line
    1! { H }       # Otherwise append to hold space
  }
  $  {             # When last line reached
    H              # Append it to hold space
    g              # Replace pattern space with hold space
    s/\n{3}//g     # Remove all occurrences of \n{3}
    p              # Print pattern space
  }
' input.txt

Aqui está uma opção mais simples usando perl , mas funciona da mesma maneira:

perl -e '
  $/ = undef;      # Slurp mode, read whole file
  $_ = <>;         # Read file to $_
  s/\n{3}//g;      # Remove all occurrences of \n{3}
  print;           # Output $_
' input.txt

Editar

Uma versão mais curta de perl sugerida por Peter O.:

perl -0777 -pe 's/\n{3}//g' input.txt
  • -0777 ativa o modo de slurp.
  • -p implicitamente imprime resultado.
por 28.07.2012 / 16:23