Gravar variável contendo texto grande com \ n em um arquivo com interpretadores de shell comuns. Como você faz isso?

4

Ambiente: linux shell ou melhor, ash shell no busybox (exemplo system: Openwrt).

Dada uma variável de string com grande texto "${a}" construído desta forma:

for index in $(seq 1 40000); do #it is 40000 for a reason, it helps if you want to reproduce the error on your system.
   a="${a}""\n""word ${index}"
done

e dado o fato de que tentar usar essa variável como argumento para comando comum produz um erro, por exemplo:

echo "${a}" #fails
awk -v VAR_A="${a}" '<program>' #fails

(as falhas são devidas: link )

Como você escreve essa variável em um arquivo de texto, possivelmente usando apenas comandos simples e não o sed / awk / perl / outro poderoso interpretador.

Idealmente, o arquivo de texto deve se parecer com:

word 1
word 2
word 3
...

e não como:

word 1\nword 2\nword 3\n...

Update1: Alguém pergunta "Por que você não pode alterar o script que produz a variável $a ?". Porque eu não posso devido a, digamos, falta de autorização (" o script estava funcionando até hoje, então você pode corrigir apenas a parte de impressão "). Então, $a e seu formato são fornecidos, só posso encontrar uma maneira de imprimi-lo em um arquivo.

Update2: Usando a sugestão "aqui docs" resolvemos a maioria dos problemas, mas ainda assim tenho o conteúdo impresso em uma linha. Talvez seja minha configuração?

    
por Pierfrancesco PierQR Aiello 04.08.2014 / 18:59

2 respostas

5

Você pode fazer um documento aqui e usar cat :

$ cat <<EOT >output
$a
EOT
$ wc -l output
40000

Eu não sei exatamente quão poderoso é o ash do seu Busybox (é configurável), mas isso deve funcionar em qualquer lugar, mesmo sem nenhum built-in. Ele expande o valor da variável em um quase-arquivo, que é então dado a cat , em vez de colocar o próprio valor na linha de comando.

Como você parece ter o literal "\n" em sua string da qual deseja se livrar, também é possível usar a substituição de string durante a substituição do parâmetro. Isso pode ser configurado fora do ash do Busybox, caso em que você terá que ir para sed . Se você tem essa extensão (não POSIX), você pode usar ${var//\\n/$NEWLINE} :

$ busybox ash
$ foo="x\ny\nz"
$ echo "$foo"
x\ny\nz
$ NEWLINE="
"
$ echo "${foo//\\n/$NEWLINE}"
x
y
z

Esta é a mesma sintaxe como Bash ; ${var/pattern/replacement} , onde pattern é global se começar com / . Parece que o seu ash foi muito configurado, então isso pode não estar lá. Nesse caso, você provavelmente terá que usar sed , embora eu ache que o uso criterioso de IFS e read permita que você trabalhe em torno disso e reconstrua uma sequência correta.

    
por 04.08.2014 / 23:17
1
busybox seq -s'
word ' 4000 | 
sed '/000/w /dev/fd/2' |  
wc -l

OUTPUT

word 1000
word 2000
word 3000
word 4000
4000

Você deve conseguir usar apenas busybox doseq incorporado e especificar word como separador. Então você pode >redirect para um arquivo, se desejar. No exemplo acima eu dividi para sed apenas para que você pudesse ter uma idéia da saída sem ter que olhar para 4000 linhas - mas elas foram todas impressas. Se o seu busybox não suportar isso, atualize .

Então, basicamente, tudo o que você precisa para toda essa coisa $a é:

busybox seq -s'
word ' $MAX_INCREMENT >$TO_FILE
    
por 04.08.2014 / 23:57