Як вкласти grep
вкладку (\ t) у файли на платформі Unix?
Як вкласти grep
вкладку (\ t) у файли на платформі Unix?
Відповіді:
Якщо ви використовуєте GNU grep, ви можете використовувати регулярний вираз в стилі Perl:
grep -P '\t' *
-P
варіант.
Хитрість полягає у використанні знака $ перед одиничними цитатами. Він також працює для різання та інших інструментів.
grep $'\t' sample.txt
zsh
а також, наскільки я можу судити. Чи можете ви прокоментувати, що таке семантика цього $
знака?
$'\t'' '
. Справжній приклад, який показує, що він працює також і з sh (не тільки bash, який за замовчуванням не встановлений на Android) busybox grep -oE '^nodev'$'\t''fuse$' /proc/filesystems
.
Мені ніколи не вдалося змусити метахарактер '\ t' працювати з грепом. Однак я знайшов два альтернативних рішення:
<Ctrl-V> <TAB>
(натискання клавіш Ctrl-V, а потім введення вкладки)foo | awk '/\t/'
| awk '/\t/'
Рішення буде працювати для всіх оболонок, платформ і систем.
awk
Тут добре працює, але в деяких тестах на моїй машині з дуже великими файлами це на 30% повільніше, ніж використання grep -P
. Це може бути банальним і неактуальним залежно від випадку використання, а awk
може бути кращим просто для читабельності та переносимості.
З цієї відповіді на запитання Ubuntu:
Скажіть grep використовувати регулярні вирази, визначені Perl (Perl має
\t
вкладку):grep -P "\t" <file name>
Використовуйте буквальний символ вкладки:
grep "^V<tab>" <filename>
Використовуйте
printf
для друку символу вкладки для вас:grep "$(printf '\t')" <filename>
Один із способів є (це з Bash)
grep -P '\t'
-P
вмикає регулярні вирази Perl, тому \ n буде працювати.
Як користувач розмотує каже, може бути специфічними для GNU Grep. Альтернатива - буквально вставити туди вкладку, якщо оболонка, редактор або термінал дозволять це.
Ще один спосіб вставлення вкладки буквально всередині виразу - це використання менш відомих $'\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`
Це не саме те, що ви шукаєте, але може працювати у вашому випадку
grep '[[:blank:]]'
Дорівнює
grep -P '[ \t]'
Так він знайде простір і вкладку.
Зауважте, він не рекламується в моєму man grep
, але все ще працює
$ man grep | grep blank | туалет 0 0 0
-P
аргумент був доданий.
В основному є два способи вирішити це:
( Рекомендовано ) Використовуйте синтаксис регулярних виразів, підтримуваний 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 (( pcregrep
GNU 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 ...
Передайте символ вкладки у шаблон. Це зрозуміло, коли ви редагуєте файл сценарію:
# 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 ...
використовувати gawk, встановити роздільник поля на табуляцію (\ t) і перевірити кількість полів. Якщо більше 1, то є / є вкладки
awk -F"\t" 'NF>1' file
awk /\t/
є достатнім для питання ОП.
Хороший вибір - використовувати «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 спосіб, який працює в ksh, dash тощо: використовуйте printf для вставки TAB:
grep "$(printf 'BEGIN\tEND')" testfile.txt
grep "$(printf '\t')" testfile.txt
Використання методу '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: Очевидно, вищесказане корисно лише для перегляду вмісту файлів для пошуку вкладок --- якщо метою є обробка вкладок як частина більшого сеансу сценаріїв, це не служить корисній меті.
Це добре працює для AIX. Я шукаю рядки, що містятьJOINED<\t>ACTIVE
voradmin cluster status | grep JOINED$'\t'ACTIVE
vorudb201 1 MEMBER(g) JOINED ACTIVE
*vorucaf01 2 SECONDARY JOINED ACTIVE
Ви можете скористатися grep "$(echo -e '\t')"
Єдина вимога - echo
вміти інтерпретувати ухили від нахилу.
Ці альтернативні методи бінарної ідентифікації є повністю функціональними. І мені дуже подобається використання awk, тому що я не міг повністю запам'ятати синтаксичне використання з єдиними бінарними символами. Однак також повинно бути можливим призначити змінній оболонки значення переносним способом POSIX (тобто TAB = echo "@" | tr "\100" "\011"
), а потім використовувати її звідти скрізь, на портативному способі POSIX; також (наприклад, grep "$ TAB" ім'я файлу). Хоча це рішення добре працює з TAB, воно також буде добре працювати з іншими бінарними символами, коли в призначенні використовується інше бажане бінарне значення (замість значення для символу TAB до 'tr').
Позначення $ '\ t', подане в інших відповідях, є специфічним для оболонки - воно, здається, працює в bash і zsh, але не є універсальним.
ПРИМІТКА. Наступне стосується fish
оболонки і не працює в bash :
У fish
оболонці можна використовувати без котирування \t
, наприклад:
grep \t foo.txt
Або ви можете використовувати шістнадцяткові або unicode позначення, наприклад:
grep \X09 foo.txt
grep \U0009 foo.txt
(ці позначення корисні для більш езотеричних персонажів)
Оскільки ці значення повинні бути без котирування, можна об'єднати цитовані та котирувані значення шляхом конкатенації:
grep "foo"\t"bar"
Ви можете набрати
grep \ t foo
grep '\ t' foo
для пошуку символу вкладки у файлі foo. Ви, ймовірно, також можете робити інші коди евакуації, хоча я лише перевірив \ n. Хоча це досить трудомістко, і незрозуміло, чому ви цього хочете, в zsh ви також можете ввести символ вкладки, повернутися до початку, зібрати та додавати вкладку цитатами.
Шукайте порожні пробіли багато разів [[: space:]] *
grep [[: простір:]] * '.' '.'
Знайдемо щось подібне:
"вкладка" ..
Це поодинокі цитати ('), а не подвійні (").
Ось так ви робите конкатенацію в grep. = -)
grep "<Ctrl+V><TAB>"
, це працює (якщо перший раз: введітьgrep "
потім натисніть комбінацію клавіш Ctrl + V, потім натисніть клавішу TAB, потім наберіть"
і натисніть клавішу Enter, voilà!)