Як вкласти 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 (( 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 ...
Передайте символ вкладки у шаблон. Це зрозуміло, коли ви редагуєте файл сценарію:
# 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à!)