Substitui um padrão em um arquivo com uma cadeia longa

3

Estou escrevendo um pequeno script de shell para gerar uma listagem de diretórios. Para tornar a saída facilmente personalizável, o script apenas constrói uma tabela HTML e deve substituir um token específico em um arquivo de modelo por essa tabela e gravá-la em stdout .

Exemplo:
Arquivo de modelo:

<!doctype html>
<html>
    <head><title>Directory Listing</title></head>
    <body>
        {{LISTING}}
    </body>
</html>

{{LISTING}} deve ser substituído pela listagem (que é armazenada em uma variável shell).

O problema aqui é que um simples sed 's/{{LISTING}}/$listing/' seria limitado ao tamanho máximo do argumento que não funciona com listagens longas.

Como posso substituir um padrão em um arquivo por uma string longa usando utilitários POSIX?

EDIT:
Para adicionar mais esclarecimentos: minha solução atual é assim:

awk '{ gsub(A, B); print; }' A="{{LISTING}}" B="$listing" < $template

$listing é expandido à medida que o awk é invocado, mas isso pode exceder os limites de tamanho do argumento, pois $listing pode ser realmente longo. Por exemplo, ao gerar uma listagem de /usr/lib , recebo um erro:

/bin/awk: Argument list too long

Estou pensando se há uma solução para substituir um padrão em um arquivo de texto com stdin .

    
por Wilhelm Schuster 12.10.2013 / 20:25

2 respostas

1

Se houver 3 arquivos:

  • old: os dados originais
  • replace: o lote grande de texto que você deseja inserir
  • newfile: onde as substituições serão salvas

Você deve ser capaz de fazer o seguinte com um shell padrão

#!/bin/sh
for line in 'cat old'; do
  if [ $line == "text to match" ]; then
    cat replace >> newfile
  else
    echo $line >> newfile
  fi
done
    
por 12.10.2013 / 20:39
0

Que tal usar xargs , pois sabe sobre limites de tamanho de argumento:

cp "$template_file" "$output_file" || exit 1
echo "$listing" \
| xargs -I arg sed -i 's/{{LISTING}}/arg {{LISTING}}/' "$output_file" \
| sed -i 's/ {{LISTING}}//' "$output_file"

A ressalva aqui é que xargs retira novas linhas nos nomes dos arquivos.

    
por 13.10.2013 / 12:17