Як підключити вкладки без використання буквальних вкладок і чому це не працює?


146

Під час пошуку вкладок у файлі з (e) grep я використовую litteral tab ( ^v + <tab>). Я не можу використовувати \tв якості заміни вкладки в регулярних виразах. З напр. Sed цей вираз працює дуже добре.

Тож чи є можливість використовувати нелітеральну заміну <tab>і для чого фони непрацюючих / не інтерпретованих \t?


Відповіді:


206

grep використовує регулярні вирази, визначені POSIX . З будь-яких причин POSIX не визначено \tяк вкладку.

У вас є кілька альтернатив:

  • скажіть grep використовувати регулярні вирази, визначені perl (perl має \tяк вкладку):

    grep -P "\t" foo.txt

    сторінка man попереджає, що це "експериментальна" особливість. принаймні, \tздається, працює добре. але більш вдосконалені функції регексу perl можуть не робити.

  • використовуйте printf для друку символу вкладки для вас:

    grep "$(printf '\t')" foo.txt
  • використовувати буквальний символ вкладки:

    grep "^V<tab>" foo.txt

    тобто: введіть grep ", потім натисніть ctrl+v, потім натисніть tab, а потім введіть " foo.txt. натискання ctrl+vв терміналі призводить до того, що наступна клавіша буде прийнята дослівно. це означає, що термінал буде вставляти символ табуляції замість того, щоб запускати якусь функцію, прив'язану до клавіші вкладки.

  • використовувати функцію цитування ansi c bash:

    grep $'\t' foo.txt

    це працює не у всіх оболонках.

  • використовувати awk:

    awk '/\t/'
  • використовувати sed:

    sed -n '/\t/p'

Дивіться статтю у вікіпедії про регулярні вирази для огляду визначених класів символів у POSIX та інших системах.


ґрунтуючись на відповіді enzotib, дозвольте додати наступне: grep $'\t' foo.txt(але я б зазвичай писав fgrepзамість grep)
Walter Tross

Мені це було потрібно в поєднанні з використанням значення змінної середовища. Я звик grep "$(printf '\t')${myvar}" foo.txt. Це добре працювало. З кількома спробами я не міг змусити останню форму працювати.
sancho.s

1
Чи є якась причина, що звичайна grepне могла мовчки інтерпретувати \tяк вкладку? Чи вимагає POSIX, що \tозначає щось інше? Можливо, це повинно відповідати лише буквальному, \ за яким слід a t?
Аарон Мак-Дейд

Можливо, варто відзначити, що BSD (включаючи OSX) грейп, не вистачає опції -P.
TextGeek

З чоловічої сторінки This is highly experimental and grep -P may warn of unimplemented features.Напевно, не дуже гарна ідея для використання -Pу застарілих системах. printfВибір краще
Avindra Goolcharan

13

Це не точно відповідь, яку ви хотіли б почути, але можливе використання послідовностей втечі надає bash

command | grep $'\t'

(не ставте це у подвійних лапках!).


1
немає необхідності в -E (те, що шукається, немає регулярного вираження). Також немає необхідності передавати команду. Це сказало, дякую, що вказали на цю цілком занедбану особливість bash (однорядкові рядки, попередні $)
Walter Tross,

2
Дійсно, я пропоную @enzotib редагувати відповідь просто grep $'\t'.
Teemu Leisti

Слід підкреслити, що це особливість bash і зробить (мовчки!) Неправильну справу, якщо виконана якоюсь іншою оболонкою (наприклад, тире, що є типовим для скриптів оболонок на Ubuntu та інших)
xjcl


1

Завжди можна вдатися до використання шістнадцяткового коду ascii для вкладки:

$ echo "one"$'\t'"two" > input.txt                                 

$ grep -P "\x9" input.txt                                          
one two

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