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