Ехо символи вкладки в скрипті bash


313

Як я повторюю один або декілька символів вкладки за допомогою скрипту bash? Коли я запускаю цей код

res='       'x # res = "\t\tx"
echo '['$res']' # expect [\t\tx]

Я це розумію

res=[ x] # that is [<space>x]

Відповіді:


529
echo -e ' \t '

відлунюватиме «пробіл у вкладці пробілу» ( -eозначає «включити інтерпретацію ухилів зворотної косої риски»):

$ echo -e ' \t ' | hexdump -C
00000000  20 09 20 0a                                       | . .|

Спасибі Йоханнес. Ви допомогли мені знайти таке рішення: res = '\ t \ t'x; echo -e '[' $ res ']'
kalyanji

2
Чи знаєте ви, чому echo -eце не працює з Makefiles?
dma_k

23
Це тому echo -e, що не POSIX та makeвиклики, /bin/shякі зазвичай не використовуються програмою, використовуються інтерактивно, і зазвичай не -eреалізуються. Для мобільності використовуйте printf '\t'замість цього.
Jo So

У Дарвіні (macOS) manсторінка для echoкоманди не згадує варіант -e. Однак цей варіант прийнятий.
ePi272314

75

Використовуйте printf, не echo.

Існує кілька різних версій echoкоманди. Існує /bin/echo(яка може бути, а може бути і не версія GNU Coreutils, залежно від системи), і echoкоманда вбудована в більшість оболонок. У різних версіях є різні способи (або ні в якому разі) для визначення або відключення вхідних елементів для контрольних символів.

printfз іншого боку, має значно менші варіації. Як правило /bin/printf, вона може існувати як команда, і вона вбудована в деякі оболонки (bash і zsh мають її, tcsh і ksh не мають), але різні версії набагато більше схожі між собою, ніж різні версії echo. І вам не потрібно пам’ятати параметри командного рядка (за кількома винятками; GNU Coreutils printf приймає --versionі --help, а вбудований bash printf приймає -v varдля зберігання результатів у змінній).

Для вашого прикладу:

res='           'x # res = "\t\tx"
printf '%s\n' "[$res]"

І тепер мені прийшов час визнати, що echoтак само буде добре для прикладу, про який ви просите; вам просто потрібно поставити подвійні лапки навколо аргументу:

echo "[$res]"

як писав kmkaplan (два з половиною роки тому, я щойно помітив!). Проблема з оригінальними командами:

res='           'x # res = "\t\tx"
echo '['$res']' # expect [\t\tx]

не з echo; це те, що оболонка замінила вкладку пробілом, перш ніж echoколи-небудь побачити її.

echoдобре, як простий вихід, як echo hello world, але ви повинні використовувати, printfколи ви хочете зробити щось складніше. Ви можете приступити echoдо роботи, але отриманий код, ймовірно, не вдасться, якщо запустити його з іншою echoреалізацією або іншою оболонкою.


1
Мені це сподобалось, він дозволяє використовувати знання printf та всі специфікатори формату.
Арун

@JezenThomas: Це не більш прихильне, оскільки відповідає на питання іншим способом, ніж просили. У питанні конкретно згадується ехо, а echo - це не дієслово, а команда.
Пауло Невес

@PauloNeves: Я б сказав, що він використовується як дієслово у питанні: "Як я повторюю один або кілька символів вкладки за допомогою скрипту bash?"
Кіт Томпсон

34

Розмістіть рядок між подвійними лапками:

echo "[$res]"

1
те саме тут - це те, що я спробував спочатку.
-це

2
@kmkaplan Робота для мене в zsh - не вдається для мене в bash
Кал

34

Ви також можете спробувати:

echo Hello$'\t'world.

4
+1 для більш загального рішення. Я використовую bash роками, і я просто зараз це навчився!
Aryeh Leib Taurog

Це набагато загальніше, ніж прийнята відповідь, оскільки її можна використовувати без відлуння.
jwan

22

вам потрібно використовувати прапор -e для відлуння, тоді ви можете

echo -e "\t\t x"

16

З сторінки "bash man":

Слова форми $ 'string "обробляються спеціально. Слово розширюється до рядка, а символи, що ухиляються від косої риски, замінюються відповідно до стандарту ANSI C.

Тож ви можете це зробити:

echo $'hello\tworld'

Чому це працює на кліпі, але не в баш-скрипті?
Фрік

13

Використовуйте дослівне натискання клавіші, ^V( CTRL+V, C-v, незалежно ).

Коли ви набираєте ^Vтермінал (або в більшості редакторів Unix), наступний символ приймається дослівно . Ви можете скористатися цим способом для введення буквального символу вкладки усередині рядка, який перегукується.

Щось на зразок наступних робіт:

echo "^V<tab>"     # CTRL+V, TAB

Документи Bash ( qv , "котирування-вставка")

quote-insert (Cq, Cv) Додайте наступний символ, який ви вводите до рядка. Наприклад, як вставити ключові послідовності, наприклад, Cq.

бічна примітка: відповідно до цього, ALT+TAB слід робити те саме, але ми всі зв'язали цю послідовність з перемиканням вікон, щоб ми не могли її використовувати

вставка табуляції (M-TAB) Вставте символ вкладки.

-

Примітка. Ви можете використовувати цю стратегію з усілякими незвичайними персонажами. Як і повернення вагона:

echo "^V^M"        # CTRL+V, CTRL+M

Це тому, що повернення вагона - ASCII 13, а M - 13-та літера алфавіту, тож при введенні ^Mви отримуєте 13-й символ ASCII. Ви можете бачити це в дії, використовуючи ls^Mпорожній запит, який вставить повернення вагона, викликаючи запит діяти так само, як ви натискаєте повернення. Коли ці символи звичайно інтерпретуються, дослівно ви отримуєте буквальний символ.


1
Бажаю, щоб я міг дати вам більше інформації за цю. Я не хотів використовувати в цьому випадку аргументи -e, і це чудово працює. Дякую!
Аарон Р.

"... більшість редакторів Unix"? Намагався вводити це як з vi, так і з emacs, і це не дало бажаних результатів ні в одному.
GreenMatt

Це так круто! І врятував мій день, коли я намагався використовувати grepдля лову рядків, що містять tabсимволи.
Joël

11

Використання ехо для друку значень змінних - це звичайна помилка Баша. Посилання:

http://mywiki.wooledge.org/BashPitfalls#echo_.24foo


Класно, мені подобаються "BashPitfalls", чудовий фрагмент матеріалу та полегшує багато болю від щоденної роботи!
Джеррі Тіан

+1, тому що це так правда. Але зауважте, що рядок kalyanji починається з "[" і не містить жодного "\".
kmkaplan

2

Якщо ви хочете використовувати echo "a\tb"в сценарії, ви запускаєте його як:

# sh -e myscript.sh

Крім того, ви можете надати myscript.sh дозвіл на виконання, а потім запустити скрипт.

# chmod +x myscript.sh
# ./myscript.sh

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.