Файл, который вы показали, содержит все детали в одной строке:
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 из них!).
.
любой символ, следовательно, .*
представляет любое количество любых символов.
;
отделяет команды, как в оболочке.