перетягніть вкладку в UNIX


417

Як вкласти grepвкладку (\ t) у файли на платформі Unix?


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

16
ctrl + v - дійсно БАД ІДЕЯ! ... так, це може працювати з консольної команди, але воно може НЕ ПРАЦЮвати на те, щоб набрати її в скрипті (ви на милість редактора, наприклад, я використовую mcedit і ctrl + v, не працюйте там)
THESorcerer

Пов’язаний, але не дублікат: пошук вкладок, без -P, за допомогою 'grep'
Peter Mortensen

Дивіться також: askubuntu.com/questions/53071/… (також пов’язано нижче)
shiri

Відповіді:


374

Якщо ви використовуєте GNU grep, ви можете використовувати регулярний вираз в стилі Perl:

grep -P '\t' *

Схоже, це не працює проти мого шаблону. Спроба використовувати цей синтаксис нічого не друкує. (Чи відрізняється варіант Mac OS X?)
futureelite7

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
Faisal Feroz

314

Хитрість полягає у використанні знака $ перед одиничними цитатами. Він також працює для різання та інших інструментів.

grep $'\t' sample.txt

7
Порада рятівника рятує життя! Він робить роботу , zshа також, наскільки я можу судити. Чи можете ви прокоментувати, що таке семантика цього $знака?
Ромен

2
Не працює, якщо рядок містить що-небудь, крім '\ t'. Як би ви шукали наприклад "\ t" (вкладка + пробіл)?
Раман

6
Раман: Можна використовувати $'\t'' '. Справжній приклад, який показує, що він працює також і з sh (не тільки bash, який за замовчуванням не встановлений на Android) busybox grep -oE '^nodev'$'\t''fuse$' /proc/filesystems.
v6ak

5
Я думаю, що $ '...' - це ідіома, що базується. Напевно, не працює в ш. Давно про csh чи tcsh.
Едвард Фолк

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

84

Мені ніколи не вдалося змусити метахарактер '\ t' працювати з грепом. Однак я знайшов два альтернативних рішення:

  1. Використання <Ctrl-V> <TAB>(натискання клавіш Ctrl-V, а потім введення вкладки)
  2. Використання awk: foo | awk '/\t/'

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

6
+1 для портативного рішення POSIX і не використовує башизми, zshism, GNUism та linuxisms.
Єнс

1
ctrl-V не корисний, якщо ви хочете скопіювати та вставити (із своїх приміток чи сценарію). Краще використовувати явне рішення, яке має видимі "\ t", буквальні табличні таблички (тобто ті, які виглядають як пробіли), часто перетворюються на SPC під час копіювання ...
plijnzaad,

awkТут добре працює, але в деяких тестах на моїй машині з дуже великими файлами це на 30% повільніше, ніж використання grep -P. Це може бути банальним і неактуальним залежно від випадку використання, а awkможе бути кращим просто для читабельності та переносимості.
theferrit32

43

З цієї відповіді на запитання Ubuntu:

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

grep -P "\t" <file name>

Використовуйте буквальний символ вкладки:

grep "^V<tab>" <filename>

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

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

1
Дослівний від http://askubuntu.com/a/53096/453741
villapx

ctrl-V не корисний, якщо ви хочете скопіювати та вставити (із своїх приміток чи сценарію). Краще використовувати явне рішення, яке має видимі '\ t', буквальні табличні
таблички

31

Один із способів є (це з Bash)

grep -P '\t'

-P вмикає регулярні вирази Perl, тому \ n буде працювати.

Як користувач розмотує каже, може бути специфічними для GNU Grep. Альтернатива - буквально вставити туди вкладку, якщо оболонка, редактор або термінал дозволять це.


Невідомий варіант P в ksh shell
Sachin Chourasiya

Як говорить розмотка, вона може бути специфічною для GNU grep. Просто уточнено.
tjmoore

Як додати вкладку? Чи не запускається процес автоматичного завершення, коли ви натискаєте кнопку вкладки? (це може працювати в баш-скрипті, але не в командному рядку)
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

Використовуйте ехо, щоб вставити вкладку для себе grep "$(echo -e \\t)"


6

В основному є два способи вирішити це:

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

    У мові регулярного вираження символ табуляції зазвичай кодується \tатомом. Атом підтримується розширеними регулярними виразами BSD ( egrep, grep -Eв сумісній системі BSD), а також сумісними з Perl RE (( pcregrepGNU 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).

    Для оболонки Борна (і не тільки) така ж поведінка може бути імітується за допомогою підстановки команд, доповненої printf (1), щоб побудувати правильний регулярний вираз:

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


2

використовувати gawk, встановити роздільник поля на табуляцію (\ t) і перевірити кількість полів. Якщо більше 1, то є / є вкладки

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

2
Це трохи зайве, і пропускає питання. awk /\t/є достатнім для питання ОП.
Обмежене спокутування

2

Хороший вибір - використовувати «sed as grep» (як це пояснено в цьому класичному підручнику з седу ).

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
Josh Rumbut

0

Відповідь простіша. Напишіть свій греп і в котируванні наберіть клавішу вкладки, вона добре працює принаймні в 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

EDIT: Очевидно, вищесказане корисно лише для перегляду вмісту файлів для пошуку вкладок --- якщо метою є обробка вкладок як частина більшого сеансу сценаріїв, це не служить корисній меті.


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

Або ви можете використовувати шістнадцяткові або unicode позначення, наприклад:

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

(ці позначення корисні для більш езотеричних персонажів)

Оскільки ці значення повинні бути без котирування, можна об'єднати цитовані та котирувані значення шляхом конкатенації:

grep "foo"\t"bar"

-4

Ви можете набрати

grep \ t foo

або

grep '\ t' foo

для пошуку символу вкладки у файлі foo. Ви, ймовірно, також можете робити інші коди евакуації, хоча я лише перевірив \ n. Хоча це досить трудомістко, і незрозуміло, чому ви цього хочете, в zsh ви також можете ввести символ вкладки, повернутися до початку, зібрати та додавати вкладку цитатами.


-6

Шукайте порожні пробіли багато разів [[: space:]] *

grep [[: простір:]] * '.' '.'

Знайдемо щось подібне:

"вкладка" ..

Це поодинокі цитати ('), а не подвійні (").
Ось так ви робите конкатенацію в grep. = -)

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