File yang Anda perlihatkan memiliki semua detail pada satu baris:
name : farah age : 23 phone number : 0123 education : degree
Saya berasumsi bahwa Anda dapat meng-hard-code age :
dll ke dalam perintah, tetapi teks yang mengikutinya akan bervariasi, dan detailnya mungkin tidak dalam urutan yang diberikan atau berdekatan.
Anda dapat mengekstrak bagian dari garis dengan grep
's -o
bendera. Ini hanya mencetak bagian yang cocok, bukan seluruh baris.
Jika Anda ingin menyertakan bagian age :
dan phone number :
, Anda dapat menggunakan -e
bendera untuk menentukan beberapa pertandingan, atau bergantian.
$ grep -oe 'age : [^ ]*' -e 'phone number : [^ ]*' file
age : 23
phone number : 0123
Ekspresi [^ ]*
berarti sejumlah karakter yang bukan spasi, sehingga cocok dengan karakter setelah age :
hingga ruang berikutnya.
Ganti file
dengan nama file yang berisi detail Anda. Anda dapat menulis file baru dengan mengarahkan output ke file baru dengan >
operator, seperti ini:
grep -oe 'age : [^ ]*' -e 'phone number : [^ ]*' file > outfile
Ketika Anda melakukan itu, Anda tidak akan melihat output apa pun. Anda harus memeriksa output terlebih dahulu, lalu tambahkan pengalihan.
Inilah contoh dengan pergantian. Kami menggunakan -E
bendera untuk memberi tahu grep
untuk menggunakan regex diperpanjang. Sintaksnya adalah (pattern1|pattern2)
- ini cocok pattern1
dan / atau pattern2
. Jika salah satu ditemukan, itu akan dicetak (terlepas dari apakah yang lain ditemukan atau tidak). Saya sekarang menggunakan +
makna setidaknya satu dari karakter sebelumnya, bukan *
berarti nol atau lebih dari karakter sebelumnya. Dalam konteks ini, keduanya bekerja sama baiknya.
$ grep -Eo '(age : [^ ]+|phone number : [^ ]+)' file
age : 23
phone number : 0123
Jika Anda ingin menghilangkan bagian age :
dan phone number:
, Anda dapat menggunakan -P
bendera untuk meminta grep
untuk menggunakan ekspresi reguler yang kompatibel dengan Perl. Ini mendukung pergantian, dan juga cara mencocokkan teks setelah pola yang diberikan:
$ grep -Po '(age : \K[^ ]+|phone number : \K[^ ]+)' file
23
0123
Jika Anda ingin memformat teks secara berbeda, Anda dapat menggunakan sed
, misalnya:
$ sed -r 's/.*(age) : ([^ ]*).*(phone number) : ([^ ]*).*/\1:\2 | \3:\4/' file
age:23 | phone number:0123
Ini tergantung pada age
kedatangan sebelumnya phone number
, jadi sesuaikanlah jika itu tidak terjadi. Jika Anda tidak dapat mengandalkan pesanan, Anda dapat menggunakan perintah yang sangat berbelit-belit ini:
$ sed -r 's/(.*)(phone number : [^ ]+)(.*) .*/\2 \1\4/; s/(phone number) : ([^ ]+) .*(age) : ([^ ]+).*/\1: \2 | \3: \4/' file
phone number: 0123 | age: 23
Ini mengatur ulang garis sehingga phone number :
bagian yang lebih dulu pada setiap baris, kemudian melakukan penggantian kedua untuk memilih detail yang diinginkan. Saya berhutang teknik yang digunakan di sini untuk jawaban ini oleh muru .
Catatan tentang sed
perintah tidak tercakup oleh penjelasan sebelumnya
-r
gunakan extended regex untuk perintah yang lebih mudah dibaca (GNU sed
mengerti -E
dengan arti yang sama)
s/old/new/
ganti old
dengannew
(pattern)
simpan pattern
untuk referensi nanti, dengan \1
atau \2
dll (sesuai dengan urutan kiri-ke-kanan di mana kelompok tangkapan terjadi - perhatikan bahwa sed
hanya akan menampung hingga 7 dari ini!).
.
karakter apa pun, karena itu .*
mewakili sejumlah karakter apa pun.
;
memisahkan perintah, seperti pada shell.