Pergunta

Em um script bash, tenho que incluir o mesmo arquivo várias vezes seguidas como argumento. Assim:

convert image.png image.png image.png [...] many_images.png

Onde image.png deve ser repetido algumas vezes.

Existe uma abreviação de rebaixamento para repetir um padrão?

Foi útil?

Solução

Isso funciona com um determinado número inteiro (10 no exemplo abaixo).

$ echo $(yes image.png | head -n10)
image.png image.png image.png image.png image.png image.png image.png image.png image.png image.png

Também pode ser usado com xargs:

$ yes image.png | head -n10 | xargs echo
image.png image.png image.png image.png image.png image.png image.png image.png image.png image.png

Outras dicas

Você pode fazer isso usando a expansão do BRACE:

convert image.png{,,} many_images.png

vai produzir:

convert image.png image.png image.png many_images.png

A expansão do BRACE repetirá a (s) sequência (s) antes (e depois) o aparelho para cada string separada por vírgula dentro dos aparelhos que produzem uma string que constê o prefixo, a sequência separada por vírgula e o sufixo; e separando as cordas geradas por um espaço.

Nesse caso, a corda separada por vírgula entre os aparelhos e o sufixo são seqüências vazias que produzirão a imagem da corda. PNG três vezes.

#!/bin/bash

function repeat {
    for ((i=0;i<$2;++i)); do echo -n $1 " "; done
}

convert $(repeat image.png 3) many_images.png

Aqui está uma solução que usa matrizes e, portanto, é robusta para cordas que contêm espaços, linhas news etc.

declare -a images
declare -i count=5
for ((i=0; i<count; ++i))
do
    images+=(image.png)
done
convert "${images[@]}" many_images.png

Isso pode funcionar para você:

convert $(printf "image.png %.s" {1..5}) many_images.png

Isso vai repetir image.png 5 vezes antes many_images.png

Para evitar o código lento que abre instâncias desnecessárias de bash usando $ (comando) ou command Você pode usar a expansão do aparelho.

Para repetir um nome de arquivo 3 vezes o faça:

file="image.png"; convert "${file[0]"{1..3}"}" many_images.png

ou uma versão mais controversa que usa uma variável para especificar o número de nomes de arquivos repetidos:

n=10; file="image.png"; eval convert \"\${file[0]\"{1..$n}\"}\" many_images.png

Como funciona.

$ {arquivo [0]} é o mesmo que $ arquivo ou $ {arquivo}

O Bash abre primeiro a expansão e, portanto, compõe uma sequência como esta:

${file[0]1} ${file[0]2} ${file[0]3}

Bash gentilmente ignore esses números extras para obter

${file[0]} ${file[0]} ${file[0]}

O que simplifica

${file} ${file} ${file}

e depois

$file $file $file

Que é o que queremos.

Mais curto Posix 7 Solução que encontrei até agora:

N=3
S="image.png "
printf "%${N}s" | sed "s/ /$S/g"

desde yes, seq e {1..3} não são posix.

Para o seu exemplo específico:

N=
convert $(printf "%${N}s" | sed "s/ /image.png /g") many_images.png
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top