grep вкладка в UNIX


418

Как мне grepвставить (\ t) в файлы на платформе Unix?


53
просто используйте grep "<Ctrl+V><TAB>", это работает (если в первый раз: введите, grep "затем нажмите комбинацию клавиш Ctrl + V, затем нажмите клавишу TAB, затем введите "и нажмите Enter, вуаля!)
— ладья

16
Ctrl + V - ДЕЙСТВИТЕЛЬНО ПЛОХАЯ ИДЕЯ! ... да, он может работать из консоли, но он может не работать, чтобы
— набрать его в сценарии


Смотрите также: askubuntu.com/questions/53071/… (ссылка также ниже)
— Шири

Ответы:


375

Если вы используете GNU grep, вы можете использовать регулярное выражение в стиле Perl:

grep -P '\t' *

Кажется, это не работает против моей картины. Попытка использовать этот синтаксис ничего не печатает. (
— Отличается

2
@futureelite: Согласно документации Apple ( developer.apple.com/Mac/library/documentation/Darwin/Reference/… ), программа grep для Mac OS X должна поддерживать параметр -P. Попробуйте создать новый вопрос на сайте superuser.com.
— расслабиться

3
Это очень хорошо для GNU UNIX, но как насчет POSIX Solaris, AIX и HP-UX? Те, кто ничего не знает о -Pварианте.
— Ладья

21
@rook GNU не UNIX.
— Лили Чанг

5
в Mac OSX вы можете задать шаблон, используя -e
— Фейсал Фероз

314

Хитрость заключается в использовании знака $ перед одинарными кавычками. Это также работает для резки и других инструментов.

grep $'\t' sample.txt

7
Спасательный круг спасает жизни! Он делает работу , zshа также, насколько я могу судить. Не могли бы вы прокомментировать семантику этого $знака?
— Romain

2
Не работает, если строка содержит что-либо кроме '\ t'. Как бы вы искали "\ t" (табуляция + пробел) например?
— Раман

6
Раман: Вы можете использовать $'\t'' '. Реальный пример, который показывает, что он работает также с sh (не только bash, который по умолчанию не установлен на Android) - это busybox grep -oE '^nodev'$'\t''fuse$' /proc/filesystems.
— v6ak

5
Я думаю, что $ '...' - идиома bash. Вероятно, не работает в ш. Не знаю про csh или tcsh.
— Эдвард Фальк

5
От 'man bash': слова вида $ 'string' обрабатываются специально. Слово расширяется до строки, символы с обратной косой чертой заменяются в соответствии со стандартом ANSI C. Escape-последовательности с
— обратной

84

Мне никогда не удавалось заставить метасимвол '\ t' работать с grep. Однако я нашел два альтернативных решения:

  1. Использование <Ctrl-V> <TAB>(нажатие Ctrl-V, затем ввод с клавиатуры)
  2. Использование awk: foo | awk '/\t/'

4
| awk '/\t/'Решение будет работать для всех оболочек, платформ и систем.
— Самвин

6
+1 для портативного решения POSIX и не использующего bashisms, zshism, GNUism и linuxisms.
— Йенс

1
Ctrl-V бесполезен, если вы хотите скопировать-вставить (из ваших заметок или скрипта). Лучше использовать явное решение, которое имеет видимые '\ t', буквенные TAB (то есть те, которые выглядят как пробельные символы) часто преобразуются в SPC при копировании ...
— plijnzaad

awkЗдесь хорошо работает, но в некоторых тестах на моей машине с очень большими файлами это примерно на 30% медленнее, чем при использовании grep -P. Это может быть тривиально и неактуально в зависимости от варианта использования, а awkможет быть лучше просто для удобства чтения и переносимости.
— theferrit32

43

Из этого ответа на Ask Ubuntu:

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

grep -P "\t" <file name>

Используйте буквенный символ табуляции:

grep "^V<tab>" <filename>

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

grep "$(printf '\t')" <filename>


Ctrl-V бесполезен, если вы хотите скопировать-вставить (из ваших заметок или скрипта). Лучше использовать явное решение, которое имеет видимые '\ t', буквенные TAB (то есть те, которые выглядят как пробельные символы) часто преобразуются в SPC при копировании
— plijnzaad

31

Один способ (это с Bash)

grep -P '\t'

-P включает регулярные выражения Perl, так что \ t будет работать.

Как говорит пользователь unwind , это может быть связано с GNU grep. Альтернативой является буквально вставить туда вкладку, если оболочка, редактор или терминал это разрешат.


Неизвестная опция P в оболочке ksh
— Sachin Chourasiya

Как говорит раскрутка, может быть специфичным для GNU grep. Только что уточнил.
— tjmoore

Как добавить вкладку? Не запускается ли процесс автозавершения при нажатии кнопки табуляции? (это может работать в скрипте bash, но не в командной строке)
— AntonioCS

1
@AntonioCS, как отмечено выше SamKrieg, для того, чтобы Shell позволяла вам вводить любой символ, сначала наберите CTRL-v. См. Также askubuntu.com/questions/53071/…
— Дени Арно

2
-P специфичен для grep, а не для любой оболочки. -P должен работать в любой оболочке, при условии, что GNU grep установлен
— plijnzaad

13

Еще один способ вставить вкладку буквально в выражение - использовать менее известную $'\t'цитату в Bash:

grep $'foo\tbar'        # matches eg. 'foo<tab>bar'

(Обратите внимание, что если вы подходите для фиксированных строк, вы можете использовать это в режиме '-F'.)

Иногда использование переменных может сделать запись более читабельной и управляемой:

tab=$'\t'               # `tab=$(printf '\t')` in POSIX
id='[[:digit:]]\+'
name='[[:alpha:]_][[:alnum:]_-]*'
grep "$name$tab$id"     # matches eg. `bob2<tab>323`

10

Это не совсем то, что вы ищете, но может работать в вашем случае

grep '[[:blank:]]'

Эквивалентно

grep -P '[ \t]'

Так он найдет пробел и таб.

§ Классы персонажей

Обратите внимание, это не рекламируется по моему man grep, но все еще работает

$ man grep | grep blank | Туалет
      0 0 0

@ A-letubby Теперь работает с правкой - -Pаргумент добавлен.
— Villapx

6

Используйте echo, чтобы вставить вкладку для вас grep "$(echo -e \\t)"


6

Есть два основных способа решения этой проблемы:

  1. ( Рекомендуется ) Используйте синтаксис регулярного выражения, поддерживаемый grep (1). Современный grep (1) поддерживает две формы синтаксиса регулярных выражений POSIX 1003.2: базовые (устаревшие) RE и современные RE. Синтаксис подробно описан на man-страницах re_format (7) и regex (7), которые являются частью систем BSD и Linux соответственно. GNU grep (1) также поддерживает Perl-совместимые RE, предоставляемые библиотекой pcre (3).

    На языке регулярных выражений символ табуляции обычно кодируется \tатомом. Атом поддерживается BSD расширенного регулярных выражений ( egrep, grep -Eна BSD совместимой системы), а также на Perl-совместимых УЭ ( pcregrepГНУ grep -P).

    Как базовые регулярные выражения, так и расширенные RE Linux, по-видимому, не поддерживают \t. Обратитесь к справочной странице утилиты UNIX, чтобы узнать, какой язык регулярных выражений он поддерживает (отсюда разница между регулярными выражениями sed (1), awk (1) и pcregrep (1)).

    Поэтому в Linux:

    $ grep -P '\t' FILE ...
    

    На BSD похожей системе:

    $ egrep '\t' FILE ...
    $ grep -E '\t' FILE ...
    
  2. Передайте символ табуляции в шаблон. Это просто, когда вы редактируете файл скрипта:

    # no tabs for Python please!
    grep -q '   ' *.py && exit 1
    

    Однако при работе в интерактивной оболочке вам может потребоваться использовать возможности оболочки и терминала для ввода правильного символа в строку. На большинстве терминалов это можно сделать с помощью комбинации клавиш Ctrl+, Vкоторая инструктирует терминал обрабатывать буквально следующий вводимый символ ( Vдословно):

    $ grep '<Ctrl>+<V><TAB>' FILE ...
    

    Некоторые оболочки могут предлагать расширенную поддержку для набора команд. Такие, в bash (1) слова формы $'string'обрабатываются специально:

    bash$ grep $'\t' FILE ...
    

    Пожалуйста, обратите внимание, хотя, будучи хорошим в командной строке, это может вызвать проблемы совместимости, когда скрипт будет перемещен на другую платформу. Кроме того, будьте осторожны с кавычками, когда используете специальные предложения, пожалуйста, обратитесь к bash (1) для деталей.

    Для оболочки Bourne (и не только) такое же поведение можно эмулировать, используя подстановку команд, дополненную printf (1), для создания правильного регулярного выражения:

    $ grep "`printf '\t'`" FILE ...
    


2

используйте gawk, установите разделитель полей на tab (\ t) и проверьте количество полей. Если больше 1, то есть / есть вкладки

awk -F"\t" 'NF>1' file

2
Это немного излишне, и пропускает вопрос. awk /\t/достаточно для вопроса оп.
— Ограниченное искупление

2

Хороший выбор - использовать sed as grep (как объясняется в этом классическом уроке sed ).

sed -n 's/pattern/&/p' file

Примеры (работает в bash, sh, ksh, csh, ..):

[~]$ cat testfile
12 3
1 4 abc
xa      c
        a       c\2
1 23

[~]$ sed -n 's/\t/&/p' testfile 
xa      c
        a       c\2

[~]$ sed -n 's/\ta\t/&/p' testfile
        a       c\2

1

+1 способ, который работает в ksh, dash и т.д .: используйте printf для вставки TAB:

grep "$(printf 'BEGIN\tEND')" testfile.txt

Это не сработало для меня в Ubuntu Trusty (Bash 4.3.11), хотя сработало следующее:grep "$(printf '\t')" testfile.txt
— Джош Рамбут

0

Ответ проще. Напиши свой grep и в кавычках набери клавишу tab, она хорошо работает как минимум в ksh

grep "  " *

3
сначала вам нужно суметь ввести символ TAB в вашей оболочке - большинство оболочек интерпретирует этот ключ как команду (завершение)
— Kaii


0

Использование метода «sed-as-grep», но замена вкладок видимым символом личных предпочтений - мой любимый метод, поскольку он четко показывает, какие файлы содержат запрашиваемую информацию, а также где она находится в строках:

sed -n 's/\t/\*\*\*\*/g' file_name

Если вы хотите использовать информацию о строке / файле или другие параметры grep, но также хотите увидеть видимую замену символа табуляции, вы можете добиться этого с помощью

grep -[options] -P '\t' file_name | sed 's/\t/\*\*\*\*/g'

Например:

$ echo "A\tB\nfoo\tbar" > test
$ grep -inH -P '\t' test | sed 's/\t/\*\*\*\*/g'
test:1:A****B
test:2:foo****bar

РЕДАКТИРОВАТЬ: Очевидно, что выше это полезно только для просмотра содержимого файла, чтобы найти вкладки - если цель состоит в том, чтобы обрабатывать вкладки как часть большего сеанса сценариев, это не служит какой-либо полезной цели.


0

Это хорошо работает для AIX. Я ищу строки, содержащиеJOINED<\t>ACTIVE

voradmin cluster status | grep  JOINED$'\t'ACTIVE

 vorudb201   1       MEMBER(g) JOINED        ACTIVE
*vorucaf01   2       SECONDARY JOINED        ACTIVE

0

Вы можете использовать grep "$(echo -e '\t')"

Единственное требование - echoбыть способным интерпретировать обратную косую черту.


0

Эти альтернативные методы двоичной идентификации полностью функциональны. И мне очень нравится тот, кто использует awk, так как я не мог вспомнить использование синтаксиса с одиночными двоичными символами. Однако также должно быть возможно присвоить переменной оболочки значение в переносимом режиме POSIX (т.е. TAB = echo "@" | tr "\100" "\011"), а затем использовать его отовсюду, в переносимом режиме POSIX; а также (т.е. имя файла grep "$ TAB"). Хотя это решение хорошо работает с TAB, оно также будет хорошо работать с другими двоичными символами, когда в назначении используется другое желаемое двоичное значение (вместо значения для символа TAB, равного 'tr').


0

Нотация $ '\ t', приведенная в других ответах, зависит от оболочки - похоже, она работает в bash и zsh, но не универсальна.

ПРИМЕЧАНИЕ: следующее для fishоболочки и не работает в bash :

В fishоболочке можно использовать без кавычек \t, например:

grep \t foo.txt

Или можно использовать шестнадцатеричные или юникодные нотации, например:

grep \X09 foo.txt
grep \U0009 foo.txt

(эти обозначения полезны для более эзотерических символов)

Поскольку эти значения должны быть заключены в кавычки, можно объединить значения в кавычках и без кавычек путем объединения:

grep "foo"\t"bar"

-4

Вы можете напечатать

grep \ t foo

или

grep '\ t' foo

искать символ табуляции в файле foo. Вы также можете использовать другие escape-коды, хотя я только протестировал \ n. Хотя это отнимает много времени и неясно, зачем вам это нужно, в zsh вы также можете ввести символ табуляции, вернуться к началу, grep и заключить вкладку в кавычки.


-6

Ищите пробелы много раз [[: space:]] *

grep [[: space:]] * '.' '.'

Найдет что-то вроде этого:

«вкладка» ..

Это одинарные кавычки ('), а не двойные (").
Так вы делаете конкатенацию в grep. = -)

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.