Файл, который вы показали, содержит все детали в одной строке:
name : farah age : 23 phone number : 0123 education : degree
Я предположил, что вы можете жестко закодировать и age :т. Д. В команду, но текст, следующий за ней, будет отличаться, и что детали могут быть не в указанном порядке или быть смежными.
Вы можете извлечь части строки с grep«S -oфлага. Это печатает только соответствующую часть, а не всю линию.
Если вы хотите включить age :и phone number :части, вы можете использовать -eфлаг, чтобы указать несколько совпадений, или чередование.
$ grep -oe 'age : [^ ]*' -e 'phone number : [^ ]*' file
age : 23
phone number : 0123
Выражение [^ ]*означает любое количество символов, которые не являются пробелами, поэтому оно соответствует символам после age :следующего пробела.
Замените fileна имя файла, который содержит ваши данные. Вы можете написать новый файл, перенаправив вывод в новый файл с >оператором, например так:
grep -oe 'age : [^ ]*' -e 'phone number : [^ ]*' file > outfile
Когда вы это сделаете, вы не увидите никакого вывода. Сначала вы должны проверить вывод, а затем добавить перенаправление.
Вот пример с чередованием. Мы используем -Eфлаг, чтобы указать grepиспользовать расширенное регулярное выражение. Синтаксис (pattern1|pattern2)- это соответствует pattern1и / или pattern2. Если один из них найден, он будет напечатан (независимо от того, найден другой или нет). Сейчас я использую +значение по крайней мере одного из предшествующих символов вместо *значения ноль или более от предыдущего символа. В этом контексте они оба работают одинаково хорошо.
$ grep -Eo '(age : [^ ]+|phone number : [^ ]+)' file
age : 23
phone number : 0123
Если вы хотите , чтобы опустить age :и phone number:детали, вы можете использовать -Pфлаг , чтобы попросить grepиспользовать Perl-совместимые регулярные выражения. Это поддерживает чередование, а также способ сопоставления текста по заданному шаблону:
$ grep -Po '(age : \K[^ ]+|phone number : \K[^ ]+)' file
23
0123
Если вы хотите отформатировать текст по-другому, вы можете использовать sed, например:
$ sed -r 's/.*(age) : ([^ ]*).*(phone number) : ([^ ]*).*/\1:\2 | \3:\4/' file
age:23 | phone number:0123
Это зависит от ageтого phone number, что наступит раньше , поэтому отрегулируйте соответственно, если это не так. Если вы не можете положиться на порядок, вы можете использовать эту очень запутанную команду:
$ sed -r 's/(.*)(phone number : [^ ]+)(.*) .*/\2 \1\4/; s/(phone number) : ([^ ]+) .*(age) : ([^ ]+).*/\1: \2 | \3: \4/' file
phone number: 0123 | age: 23
Это переставляет линию так, что phone number :сечение появляется первым в каждой строке, а затем выполняется вторая замена, чтобы выбрать нужные детали. Я обязан технике, использованной здесь, для этого ответа Муру .
Примечания к sedкомандам, не охваченным предыдущими пояснениями
-rиспользуйте расширенное регулярное выражение для более удобочитаемых команд (GNU sedпонимает -Eс тем же значением)
s/old/new/заменить oldнаnew
(pattern)сохраняет patternдля ссылки позже, с помощью \1или и \2т. д. (в соответствии с порядком слева направо, в котором встречаются группы захвата - обратите внимание, что они sedбудут содержать только до 7 из них!).
.любой символ, следовательно, .*представляет любое количество любых символов.
; отделяет команды, как в оболочке.