2 hal:
- Seperti yang dinyatakan oleh @Rory, Anda membutuhkan
-o
opsi, jadi hanya kecocokan yang dicetak (bukan seluruh baris)
- Selain itu, Anda perlu
-P
pilihan, untuk menggunakan ekspresi reguler Perl, yang mencakup elemen berguna seperti Lihat di depan (?= )
dan Lihat di belakang (?<= )
, yang mencari bagian, tetapi tidak benar-benar cocok dan mencetaknya.
Jika Anda hanya menginginkan bagian di dalam parensis yang cocok:
grep -oP '(?<=\/\()\w(?=\).+\/)' myfile.txt
jika file mengandung sengatan /(a)5667/
, grep akan mencetak 'a', karena:
/(
ditemukan oleh \/\(
, tetapi karena mereka berada dalam pandangan-belakang (?<= )
mereka tidak dilaporkan
a
dicocokkan dengan \w
dan dengan demikian dicetak (karena -o
)
)5667/
ditemukan b < \).+\/
, tetapi karena mereka dalam pandangan ke depan (?= )
mereka tidak dilaporkan
sed
referensi untuk melakukan itu?sumber
Jika Anda hanya menginginkan apa yang ada di dalam tanda kurung, Anda memerlukan sesuatu yang mendukung menangkap sub pertandingan (Kelompok Pengambilan Bernama atau Bernomor). Saya tidak berpikir grep atau egrep dapat melakukan ini, perl dan sed bisa. Misalnya, dengan perl:
Jika file yang disebut foo memiliki baris di dalamnya adalah sebagai berikut:
Dan kamu juga:
Huruf a dikembalikan. Itu mungkin bukan yang Anda inginkan. Jika Anda memberi tahu kami apa yang ingin dicocokkan, Anda mungkin mendapatkan bantuan yang lebih baik. $ 1 adalah apa pun yang ditangkap dalam set kurung pertama. $ 2 akan menjadi set kedua dll.
sumber
Karena Anda menandai pertanyaan Anda sebagai bash selain shell , ada solusi lain selain grep :
Bash memiliki mesin ekspresi regulernya sendiri sejak versi 3.0, menggunakan
=~
operator, seperti Perl.sekarang, diberikan kode berikut:
bash
dan bukan hanyash
untuk mendapatkan semua ekstensi$BASH_REMATCH
akan memberikan seluruh string sesuai dengan seluruh ekspresi reguler, jadi<Lane>8</Lane>
${BASH_REMATCH[1]}
akan memberikan bagian yang cocok dengan grup 1, dengan demikian hanya8
sumber
>
simbol untuk tujuan yang sama sekali berbeda) sebagaimana dimuntahkan oleh perangkat lunak penyelarasan skala cepat paralel SANSparallel . Tentu saja kedua format tersebut di-interlaced tanpa ada pelarian. Jadi tidak mungkin untuk melemparkan beberapa pustaka XML standar pada ini. Dan saya menggunakan Bash regex pada titik kode ini karena saya hanya perlu mengekstrak beberapa data, dan 2 regex melakukan pekerjaan lebih baik bagi saya daripada menulis pengurai khusus untuk kekacauan ini. #LifeInBioinformaticsDengan asumsi file tersebut berisi:
Dan Anda ingin karakter antara
>
dan</
, Anda dapat menggunakan:grep
grep -oP '.*\K(?<=>)\w+(?=<\/)' file
sed
sed -nE 's:^.*>(\w+)</.*$:\1:p' file
awk
awk '{print(gensub("^.*>(\\w+)</.*$","\\1","g"))}' file
perl
perl -nle 'print $1 if />(\w+)<\//' file
Semua akan mencetak string "xyz".
Jika Anda ingin menangkap digit dari baris ini:
grep
grep -oP '.*\K(?<=>)[0-9]+(?=<\/)' file
sed
sed -E 's:^.*>([0-9]+)</.*$:\1:' file
awk
awk '{print(gensub(".*>([0-9]+)</.*","\\1","g"))}' file
perl
perl -nle 'print $1 if />([0-9]+)<\//' file
sumber
echo 'Text-<here>1234</text>-ends' | sed -E 's|.*>([[:digit:]]+)<.*|\1|'
. Dalam beberapa kasus (misalnya[0-9]
vs.[[:digit:]]
) mereka tidak membantu keterbacaan, dalam kasus lain saya pikir mereka dapat membantu (misalnya[ \t\n\r\f\v]
vs.[:space:]
).Ini akan memenuhi apa yang Anda minta, tetapi saya tidak berpikir itu yang Anda inginkan. Saya meletakkan
.*
di depan regex untuk memakan apa pun sebelum pertandingan, tapi itu adalah operasi serakah, jadi ini hanya cocok dengan\w
karakter kedua dari belakang dalam string.Perhatikan bahwa Anda harus keluar dari parens dan
+
.sumber