Как повторить несколько символов несколько раз в Bash? - PullRequest
4 голосов
/ 06 августа 2010

В скрипте bash я должен включить один и тот же файл несколько раз подряд в качестве аргумента. Как это:

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

, где image.png следует повторить несколько раз.

Существует ли сокращение bash для повторения шаблона?

Ответы [ 7 ]

10 голосов
/ 06 августа 2010

Вы можете сделать это, используя расширение скобки:

convert image.png{,,} many_images.png

даст:

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

Расширение скобок будет повторять строку (и) до (и после) скобок для каждой строки, разделенной запятыми, внутри фигурных скобок, создавая строку, состоящую из префикса, разделенной запятой строки и суффикса; и разделяя сгенерированные строки пробелом.

В этом случае разделенные запятыми строки между фигурными скобками и суффиксом являются пустыми строками, которые будут генерировать строку image.png три раза.

7 голосов
/ 06 августа 2010

Это работает с данным целым числом (10 в примере ниже).

$ 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

Также может использоваться с 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
2 голосов
/ 06 августа 2010

Вот решение, которое использует массивы и, следовательно, устойчиво для строк, содержащих пробелы, переводы строки и т. Д.

declare -a images
declare -i count=5
for ((i=0; i<count; ++i))
do
    images+=(image.png)
done
convert "${images[@]}" many_images.png
2 голосов
/ 06 августа 2010
#!/bin/bash

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

convert $(repeat image.png 3) many_images.png
0 голосов

Самое короткое POSIX 7 решение, которое я нашел до сих пор:

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

, поскольку yes, seq и {1..3} не являются POSIX.

Для вашего конкретного примера:

N=
convert $(printf "%${N}s" | sed "s/ /image.png /g") many_images.png
0 голосов
/ 08 марта 2014

Чтобы избежать медленного кода, который открывает ненужные экземпляры bash с помощью $ (команда) или command, вы можете использовать расширение скобки.

Чтобы повторить имя файла 3 раза, выполните:

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

или более противоречивая версия, которая использует переменную для указания количества повторяющихся имен файлов:

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

Как это работает.

$ {file [0]} совпадает с $ file или$ {file}

Bash сначала выполняет расширение фигурной скобки, поэтому он создает последовательность, подобную этой:

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

Bash, пожалуйста, игнорируйте эти дополнительные числа, чтобы вы получили

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

Что упрощает до

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

, а затем

$file $file $file

Что мы и хотим.

0 голосов
/ 10 декабря 2011

Это может работать для вас:

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

Это будет повторяться image.png 5 раз до many_images.png

...