Cara menemukan garis yang dimulai dengan **

8

Saya perlu mencari jika ada baris dalam file yang dimulai **.

Saya tidak tahu bagaimana melakukannya karena *ditafsirkan sebagai wildcard oleh shell.

grep -i "^2" test.out

berfungsi jika garis dimulai dengan 2 tetapi

grep -i "^**" test.out 

jelas tidak bekerja.

(Saya juga perlu tahu apakah baris ini berakhir dengan )tetapi belum mencobanya).

Shar Hunter
sumber

Jawaban:

18

Gunakan \karakter untuk keluar dari * untuk menjadikannya karakter normal.

grep '^\*\*' test.out

Perhatikan juga kutipan tunggal 'dan bukan kutipan ganda "untuk mencegah shell memperluas hal-hal

Stephen Harris
sumber
3
Yang pertama *tidak perlu melarikan diri dalam kasus khusus ini, fwiw.
don_crissti
5
Meskipun tidak harus melarikan diri, tidak melarikan diri tanda bintang pertama akan lebih membingungkan dari pengamat biasa, seolah-olah Anda mencocokkan "sejumlah awal garis diikuti dengan tanda bintang". Apa pun yang membuat regexp lebih intuitif ke pengelola adalah ide yang baik. =)
Compiler mencolok
1
Menggunakan tanda kutip ganda juga akan mencegah ekspansi, tidak hanya tanda kutip tunggal. Saran yang salah di sini.
rems4e
@ rems4e menggunakan tanda kutip ganda akan mencegah shell memperluas tanda bintang, tetapi tidak menafsirkan backslash. Dengan tanda kutip ganda, Anda harus menggunakan grep "^\\*\\*"sehingga grep menerima ^\*\*string yang perlu dihindari menafsirkan tanda bintang sebagai regex quantifiers.
Aaron
7

Karena Anda ingin memeriksa garis yang dimulai **dan diakhiri dengan ), Anda dapat menggabungkan dua grepoperasi seperti ini,

grep '^*\*' test.out | grep ')$'

Atau dengan satu grepperintah seperti ini,

grep -E '^\*\*.*\)$' test.out

Penjelasan

  • ^\*\* : garis kecocokan yang dimulai dengan **
  • .* : cocokkan semuanya setelah **
  • \)$: garis pertandingan yang juga ada )di akhir baris.
Rahul
sumber
3

Itu bukan cangkangnya

Sejauh ini tidak ada jawaban yang menyentuh masalah sebenarnya. Akan sangat membantu untuk menjelaskan mengapa itu tidak bekerja seperti yang Anda harapkan.

grep -i "^**" test.out

Karena Anda telah dikutip pola untuk grep , *yang tidak diperluas oleh shell. Itu dilewatkan untuk memahami apa adanya. Ini dijelaskan di halaman manual [1] untuk bash [2] :

Menutup karakter dalam tanda kutip ganda mempertahankan nilai literal semua karakter dalam tanda kutip, dengan pengecualian $, `, \, dan, ketika ekspansi sejarah diaktifkan,!.

Ini ekspresi reguler biasa biasa

Ekspresi reguler adalah pola yang menggambarkan sekumpulan string.

*adalah salah satu pola utama dalam ekspresi reguler. Secara default, grep mengartikannya sebagai berikut:

* The preceding item will be matched zero or more times.

Ini berarti bahwa pola Anda seperti apa adanya, ^**tidak masuk akal. Mungkin itu mencoba untuk mencocokkan awal garis nol atau lebih , dua kali. Apapun maksudnya.

Solusinya adalah mengutipnya :

Setiap meta-karakter dengan makna khusus dapat dikutip dengan mendahuluinya dengan garis miring terbalik.

grep -i "^\*\*" test.out


[1] Saya tidak merekomendasikan membacanya. Silakan gunakan man dashatau serupa.

[2] Tidak ada shell yang diberikan, jadi saya berasumsi bash .

pipa
sumber
2

Pilihan lain.

Anda bisa menggunakan sedatau awkjuga

$ sed -n '/^*\*/p' test.out
$ awk '/^*\*/' test.out

Untuk mengetahui garis yang diakhiri dengan )gunakan juga grepatau sedatauawk

$ grep ')$' test.out
$ sed -n '/)$/p' test.out
$ awk '/)$/' test.out
Takomi
sumber
Terimakasih semuanya ! Saya sangat menghargai bantuan yang satu ini!
Shar Hunter
1
Dan garis awk gabungan: '/^*\*/&&/)$/'...
jasonwryan
0

Ini adalah versi sepenuhnya kuotasi: grep ^\\*\\* test.out. Untuk melewatkan backslash literal dari shell ke grep, ia harus diloloskan.

Ini berfungsi selama Anda tidak memiliki file di direktori dimulai dengan ^\dan mengandung backslash lain.

Kalahkan Bolli
sumber