LINUX.ORG.RU

printf «$@»

 , ,


0

4

Почему printf "$@" работает не как echo "$@"? Выводит только первое слово, а printf "$*" — выводит всё. В чём разница между "$@" и "$*" для printf? Почему с echo по-другому?

★★★★★

Просто '$@' разворачивается как несколько аргументов, а '$*' как один.
У printf первым аргументом идет формат и если в нем нет, например, '%s', остальные аргументы он проигнорирует.
Попробуй: printf "%s" "$@"

Lavos ★★★★★ ()
Последнее исправление: Lavos (всего исправлений: 1)
Ответ на: комментарий от teod0r

Для каждого аргумента должен быть указан формат.

Если два строковых аргумента - «%s %s», если три - «%s %s %s».

Если нужно вывести число в шестнадцатиричном формате - «%x».

Всё как в сишной функции printf.

anonymous ()
Ответ на: комментарий от anonymous

а как быть, когда не знаешь сколько будет аргументов, а echo не подходит из-за того, что оно неправильно обработает аргументы -n -e?

teod0r ★★★★★ ()
Ответ на: комментарий от teod0r

а как быть, когда не знаешь сколько будет аргументов

юзай сишку. Там ASCIIZ, и такой проблемы нет, ну или может xargs поможет.

Ты явно что-то не так делаешь.

ЗЫЖ возможно поможет:

#!/bin/bash

declare -a ARRAY

ARRAY=( "1 1 2" "2 3 4" "5" )
for S in "${ARRAY[@]}"; do
	echo "'$S'"
done

emulek ()
Ответ на: комментарий от anonymous

Всё как в сишной функции printf.

printf(1) это «жалкое подобие левой руки» ☺

emulek ()
Ответ на: комментарий от teod0r

Во-первых, "$@" и "$*" разворачивает шелл. "$@" — это «передать все аргументы как есть»; "$*" — это «все аргументы, склеенные первым символом из $IFS». Так что

а как быть, когда не знаешь сколько будет аргументов, а echo не подходит из-за того, что оно неправильно обработает аргументы -n -e?

join-by-space() {
    local IFS=' '
    printf '%s\n' "$*"
}

join-by-space one two three
anonymous ()
Ответ на: комментарий от anonymous

printf '%s\n' "$*"

так printf "$*" и так работает, я уже писал. а если именно "$@" надо? вдруг такая ситуация нужна будет...

teod0r ★★★★★ ()
Ответ на: комментарий от teod0r

printf «$*» и так работает

Ну что за <censored>! Не работает же с %, \. Пойми уже, как работают bash и printf.

а если именно «$@» надо? вдруг такая ситуация нужна будет

Зачем? Приведённая функция делает именно то, что ты описал: выводит все аргументы через пробел. Чем это будет отличаться от

join-by-space() {
    printf магическая-строка-которую-ты-тут-ищешь "$@"
}

?

anonymous ()
Ответ на: комментарий от anonymous

Не работает же с %

ну так с '%s' работает. чем это на пробелы в "$*" влияет?

Зачем?

чтоб в дальнейшем обработать аргументы по отдельности.

teod0r ★★★★★ ()
Ответ на: комментарий от teod0r

ну так с '%s' работает. чем это на пробелы в «$*» влияет?

"$*" — «все аргументы, склеенные первым символом из $IFS»; "$@" — «все аргументы как есть».

printf, когда у него заканчиваются форматы, начинает сначала, т.е. printf %s a b c эквивалентно printf %s%s%s a b c.

чтоб в дальнейшем обработать аргументы по отдельности.

Что.

Тебе нужно напечатать "$@" через пробел. Для этого ты вызываешь join-by-space "$@". В чём проблема?

anonymous ()
Ответ на: комментарий от anonymous

не понял тебя, что ты имел в виду, говоря, что не работает с %

правильно ли я понимаю, что echo "$*" и echo "$@" выдадут абсолютно идентичные результаты?

teod0r ★★★★★ ()
Ответ на: комментарий от teod0r

вот заместо «1 1 2» подставь -e или -n, и чтоб echo «$S» было без одинарных кавычек

с дуру можно и хрен сломать.

Да, echo не умеет --, и воспринимает -e и -n как опции. Ну и что?

emulek ()

Потому-что в отличии от echo, выводящего абсолютно все переданные ему аргументы, printf действует в соответствии с форматной строкой, которая в случае printf "$@" 1 2 3" равна единице, т.к. "$@" преобразуется в пустоту и не считается за аргумент:

$ ./printf "$@" 1 2 3 
argc = 4
1
$ ./printf 1 2 3      
argc = 4
1 
edigaryev ★★★★★ ()
Ответ на: комментарий от edigaryev

т.е. с помощью printf вывести «$@» как это делает echo в принципе не возможно?

teod0r ★★★★★ ()
Ответ на: комментарий от teod0r

Какой же ты тупой.

правильно ли я понимаю, что echo «$*» и echo «$@» выдадут абсолютно идентичные результаты?

$ set -- -n -e
$ echo "$*"
-n -e
$ echo "$@"
$
$ set -- 1 2 3
$ IFS=:
$ echo "$*"
1:2:3
$ echo "$@"
1 2 3
$
anonymous ()
Ответ на: комментарий от edigaryev

кажется, наконец понял что нужно было

printf '%s ' "$@"

teod0r ★★★★★ ()
Ответ на: комментарий от anonymous

Какой ты тупой

разве не ты втирал "Зачем?"? "Оно же всё равно на пробелы заменяется".
так мне именно "$@" и нужно было, а не разделители в "$*"

teod0r ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.