$ echo foo
foo
Это вызывает echo
с аргументом foo и выводится foo .
$ /bin/sh -c echo foo
Это вызывает оболочку с аргументом echo
и предоставляет foo в качестве аргумента
$ 0
. echo
выводит новую строку, и вы отбрасываете foo . Если вы хотите
вывести foo , укажите аргумент:
sh -c 'echo foo'
или используйте указанный аргумент:
sh -c 'echo $0' foo
В этом примере
$ /bin/sh -c 'echo foo; echo bar'
foo
bar
Оболочка вызывается с аргументом эхо фу; эхо-панель
, которая выводит
foo
bar
Предложение:
#!/bin/bash
make_readme () {
printf '%s\n%s\n' "$1" "$( eval "printf '=%.0s' {1..${#1}}" )"
}
make_readme 'Hello World!' >README.md
или, если вызов внешней утилиты в порядке,
#!/bin/bash
make_readme () {
# print $1, then replace all characters in it with = and print again
sed 'p; s/./=/g' <<<"$1"
}
make_readme 'Hello World!' >README.md
Оба они создают файл с именем README.md
, содержащий
Hello World!
============
Если вам не нужно использовать оболочку bash
, используйте вместо нее zsh
:
make_readme() printf '%s\n' $1 ${(l[$#1][=])}
Где (l[length][string])
— левый -флаг расширения параметра заполнения (, который здесь вообще не применяется к параметру ).
Учитывать ширину отображения каждого символа, чтобы лучше работать с текстом, содержащим символы нулевой -ширины или двойной -ширины:
$ make_readme() printf '%s\n' $1 ${(l[$#1*3-${#${(ml:$#1*2:)1}}][=])}
$ make_readme $'Ste\u0301phane'
Stéphane
========
$ make_readme 'FOOBAR'
FOOBAR
============
(это U+FF21..U+FF3A заглавные английские буквы двойной ширины; ваш браузер может не отображать их как двойную -ширину, но ваш терминал должен ).
${(ml:width:)1}
дополняет $1
до width
, принимая во внимание ширину отображения каждого символа, что позволяет нам вычислить ширину отображения $1
путем сравнения количества символов в $1
с количеством символов, если дополняется вдвое большим количеством символов. Подробнее см. Получение ширины отображения строки символов .
Я предлагаю:
make_readme () {
printf '%s\n%s\n' "$1" "${1//?/=}"
}
make_readme 'Hello World!' >README.md
Для вашей фактической проблемы , которая заключается в том, что «дана строка, создайте ту же -длину строку = = Я согласен с другими ответами на изменение строки с использованием bash, zsh, tr, sed и т. д.
Но для вашего поставленного вопроса , который заключается в том, что «данное число создает строку такой длины», причина, по которой ваш подход не сработал, заключается в том, что bash выполняет «расширение параметров» который включает${#1}
после расширения скобки ; см. руководство или информацию в разделе «Расширения оболочки» .
Некоторые способы, которыми вы можете создать строку, заданную только длиной:
%.0s
, но с программойseq
вместо раскрытия фигурных скобок (, потому что подстановка команд создает подоболочку, которая выполняется первой, и выполняет раскрытие параметров): printf '%s\n' "$1"; printf '=%.0s' $( seq ${#1} ); printf '\n'
printf
для создания заполнения, а затем измените его: # create a string of spaces equal to length of $1, then convert spaces to =
t=$(printf '%*s' ${#1} ''); printf '%s\n' "$1" "${t// /=}"
# create a string of zeros equal to length of $1, then convert zeros to =
t=$(printf '%0*d' ${#1} 0); printf '%s\n' "$1" "${t//0/=}"
printf '%s\n' "$1" "$( perl -e "print '='x${#1}" )"
# quoting $(perl...) isn't needed when we know (all) the chars are =
# but is good practice in general
# note I reverse the more common method of singlequoting a perl script
# with internal strings doublequoted, because I _want_ shell expansion
Попробуйте
printf "%s\n%.*s\n" "$1" "${#1}" "$(printf "%.0s=" {1..30})"
Some project
============