Domanda

In uno script bash, devo includere lo stesso file parecchie volte di fila come argomento. In questo modo:

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

dove image.png deve essere ripetuto un paio di volte.

C'è una scorciatoia bash per ripetere un modello?

È stato utile?

Soluzione

Questo funziona con un dato intero (10 nell'esempio qui sotto).

$ 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

Può essere utilizzato anche con 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

Altri suggerimenti

È possibile farlo espansione delle parentesi graffe utilizzando:

convert image.png{,,} many_images.png

produrrà:

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

espansione Brace ripeterà la stringa (s) prima (e dopo) le bretelle per ogni stringa separata da virgole all'interno delle parentesi producendo una stringa consiting del prefisso, la stringa separata da virgole e il suffisso; e separando le stringhe generate da uno spazio.

In questo caso la stringa separata da virgole tra i supporti e il suffisso sono stringhe vuote che produrranno la stringa image.png tre volte.

#!/bin/bash

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

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

Ecco una soluzione che utilizza le matrici ed è quindi robusto per le stringhe contenenti spazi, a capo etc.

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

Questo lavoro potrebbe per voi:

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

Questo si ripeterà image.png 5 volte prima many_images.png

Per evitare lento codice che apre casi inutili di bash utilizzando $ (comando) o command è possibile utilizzare espansione delle parentesi graffe.

Per ripetere un nome di file 3 volte fanno:

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

o una versione più controverso che utilizza una variabile per specificare il numero di nomi di file ripetuti:

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

Come funziona.

{file [0]} $ è uguale a $ file o $ {file}

Bash fa espansione delle graffe prima e quindi ha una sequenza simile:

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

Bash gentilmente ignorare questi numeri in più in modo da ottenere

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

che semplifica al

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

e quindi

$file $file $file

Il che è quello che vogliamo.

POSIX 7 soluzione che ho trovato finora:

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

dal yes, seq e {1..3} non sono POSIX.

Per il vostro esempio specifico:

N=
convert $(printf "%${N}s" | sed "s/ /image.png /g") many_images.png
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top