Чому wc <<< “$ string” показує довжину на один байт довше, ніж printf “$ string” | туалет?


11

Випадково я з'ясував, що wcрахується по-різному залежно від того, як він отримує вхід від bash:

$ s='hello'
$ wc -m <<<"$s"
6
$ wc -c <<<"$s"
6
$ printf '%s' "$s" | wc -m
5
$ printf '%s' "$s" | wc -c
5

Це - ІМХО заплутане - поведінка десь задокументована? Що wcтут враховує - це припущений новий рядок?


3
Ви завжди od -cзможете побачити, що саме у вас є.
Thorbjørn Ravn Andersen

Або, краще, xxd -g1.
Руслан

1
Я сподіваюся, що printf "$s"це не ваш printf "%s" "$s"
власний

Оскільки було дуже багато коментарів щодо printf, я відредагував свою публікацію, щоб відобразити найкращу практику.
rexkogitans

Відповіді:


38

Різниця викликана новим рядком, доданим до рядка here. Дивіться посібник Bash :

Результат подається у вигляді єдиного рядка із доданим новим рядком до команди на його стандартному вході (або дескриптора файлу n, якщо вказано n ).

wc обчислюється так само, але вхід його різний.


7
Якщо слід зазначити, що для друку (довільного) вмісту змінної без доданого символу нового рядка, він повинен бути printf %s "$var"(або print -rn -- "$var"з оболонками, схожими на ksh), printf "$var"а не для коректних значень, $varщо містять %символи, що містять або звороту косу рису (або почніть з -більшості реалізацій).
Стефан Шазелас

Зауважте, що оригінальна реалізація тут-рядка в порту Unix rcне додала цього символу нового рядка.
Стефан Шазелас

26

Це успішний новий рядок, доданий перенаправленням тут-рядка:

$ s="hello"
$ hexdump -C <<<"$s"
00000000  68 65 6c 6c 6f 0a                                 |hello.|
00000006
$ printf "$s" | hexdump -C
00000000  68 65 6c 6c 6f                                    |hello|
00000005
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.