Как повторить несколько персонажей несколько раз в Bash?
-
26-09-2019 - |
Вопрос
В скрипте Bash я должен включить один и тот же файл несколько раз подряд в качестве аргумента. Так:
convert image.png image.png image.png [...] many_images.png
куда image.png
следует повторить несколько раз.
Есть ли Bash Shothand для повторения шаблона?
Решение
Это работает с заданным целым числом (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
Другие советы
Вы можете сделать это, используя расширение Brace:
convert image.png{,,} many_images.png
будет производить:
convert image.png image.png image.png many_images.png
Расширение Brace будет повторять строку (ы) до (и после) брекетов для каждой строки, разделенную запятую в скобках, создающих строковое, обоснование префикса, строку, разделенную запятую и суффикс; и разделяя порожденные строки пространством.
В этом случае запятая строка между брекетами и суффиксом - это пустые строки, которые будут производить строку image.png три раза.
#!/bin/bash
function repeat {
for ((i=0;i<$2;++i)); do echo -n $1 " "; done
}
convert $(repeat image.png 3) many_images.png
Вот решение, которое использует массивы и, таким образом, надежно для струн, содержащих пробелы, новойной линии и т. Д.
declare -a images
declare -i count=5
for ((i=0; i<count; ++i))
do
images+=(image.png)
done
convert "${images[@]}" many_images.png
Это может работать для вас:
convert $(printf "image.png %.s" {1..5}) many_images.png
Это будет повторять image.png
5 раз раньше many_images.png
Чтобы избежать медленного кода, который открывает ненужные экземпляры 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}
Bash делает расширение скобки сначала, и поэтому она составляет вроде последовательности:
${file[0]1} ${file[0]2} ${file[0]3}
Bash Пожалуйста, игнорируйте эти дополнительные номера, чтобы вы получили
${file[0]} ${file[0]} ${file[0]}
Который упрощает
${file} ${file} ${file}
а потом
$file $file $file
Который мы хотим.
Кратчайший 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