Вопрос Как grep для вкладок без использования литеральных вкладок и почему \ t не работает?


Когда я ищу вкладки в файле с (e) grep, я использую вкладку litteral (^v + <tab>). Я не могу использовать \t в качестве замены вкладок в регулярных выражениях. С помощью, например, sed это выражение работает очень хорошо.

Таким образом, есть ли возможность использовать нелитровую замену для <tab> и каковы фоны для неработающих / не интерпретируемых \t ?


117
2017-07-14 11:59


происхождения


stackoverflow.com/questions/1825552/grep-a-tab-in-unix - Ciro Santilli 新疆改造中心 六四事件 法轮功


ответы:


grep использует регулярные выражения, определенные в POSIX, По каким-либо причинам POSIX не определил \t как вкладка.

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

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

    grep -P "\t" foo.txt
    

    справочная страница предупреждает, что это «экспериментальная» функция. как минимум \t похоже, хорошо работает. но более сложные функции регулярного выражения perl могут и не быть.

  • используйте printf для печати символа табуляции для вас:

    grep "$(printf '\t')" foo.txt
    
  • используйте буквенный символ табуляции:

    grep "^V<tab>" foo.txt
    

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

  • использовать ansi c цитирование особенность bash:

    grep $'\t' foo.txt
    

    это не работает во всех оболочках.

  • использовать awk:

    awk '/\t/'
    
  • использовать sed:

    sed -n '/\t/p'
    

См. статья в Википедии о регулярных выражениях для обзора определенных классов символов в POSIX и других системах.


164
2017-07-14 15:04



исходя из ответа enzotib, позвольте мне добавить следующее: grep $'\t' foo.txt (но я обычно пишу fgrep вместо grep) - Walter Tross
Мне это нужно, в сочетании с использованием значения переменной среды. я использовал grep "$(printf '\t')${myvar}" foo.txt, Он работал нормально. С несколькими попытками я не мог получить последнюю форму для работы. - sancho.s
Есть ли причина, по которой простой grep не мог молча интерпретировать \t как вкладка? Требует ли POSIX \t что-то еще? Возможно, он должен соответствовать только буквальному \  а затем t? - Aaron McDaid
Возможно, стоит отметить, что в BSD (включая OSX) grep отсутствует опция -P. - TextGeek
На странице руководства This is highly experimental and grep -P may warn of unimplemented features. Вероятно, не рекомендуется использовать -P в устаревших системах. printf выбор лучше - Avindra Goolcharan


Это не совсем тот ответ, который вы хотели бы услышать, но возможное использование escape-последовательностей обеспечивается bash

command | grep $'\t'

(не ставьте его в двойные кавычки!).


12
2017-07-14 14:15



нет необходимости в -E (для поиска не существует регулярного выражения). Также нет необходимости подключаться к команде. Тем не менее, спасибо, что указали на эту довольно упущенную функцию bash (строки с одним кавычком, которым предшествует $) - Walter Tross
Действительно, я предлагаю, чтобы @enzotib отредактировал ответ просто grep $'\t', - Teemu Leisti
Следует подчеркнуть, что это особенность bash и будет (беззвучно!) Делать неправильную вещь, если выполняется какой-либо другой оболочкой (например, тире, которая по умолчанию используется для сценариев оболочки на Ubuntu и других) - xjcl


awk '/\t/' мой любимый обходной путь:

printf 'a\t\nb' | awk '/\t/'

Вывод: a\t,


2
2017-08-28 11:15





Всегда можно прибегнуть к использованию шестнадцатеричного кода ascii для вкладки:

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

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

$ grep $'\x9' input.txt                                            
one two

1
2017-07-03 17:04