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.