Apa yang seharusnya menjadi hasil jika inputnya Here is a Here String? Atau I Hereby Dub Thee Sir Stringy?
ghoti
5
FYI. Perintah Anda berarti mencetak segala sesuatu antara baris yang memiliki kata Di sini dan baris yang memiliki kata String - bukan yang Anda inginkan.
Terima kasih! Bagaimana jika saya ingin menemukan segalanya antara "satu adalah" dan "Tali" di "Ini adalah satu adalah Tali"? (sed -e 's / one adalah (. *) String / \ 1 /'?
user1190650
5
@ user1190650 Itu akan berfungsi jika Anda ingin melihat "Here is a" juga. Anda dapat menguji itu: echo "Here is a one is a String" | sed -e 's/one is\(.*\)String/\1/'. Jika Anda hanya ingin bagian antara "satu" dan "String", maka Anda perlu membuat regex cocok seluruh baris: sed -e 's/.*one is\(.*\)String.*/\1/'. Selain itu, s/pattern/replacement/ucapkan "gantikan 'penggantian' untuk 'pola' di setiap baris". Itu hanya akan mengubah apa pun yang cocok dengan "pola", jadi jika Anda ingin mengganti seluruh baris, Anda perlu membuat "pola" cocok dengan seluruh garis.
Brian Campbell
9
Ini rusak ketika inputnyaHere is a String Here is a String
Jay D
1
Akan lebih bagus untuk melihat solusi untuk sebuah kasus: "Ini adalah String bla bla. Berikut ini adalah Bla bla String. Berikut ini adalah 2 blash blash String". Output harus mengambil hanya substring pertama antara Here dan String "
Jay D
1
@JayD sed tidak mendukung pencocokan non-serakah, lihat pertanyaan ini untuk beberapa alternatif yang disarankan.
Brian Campbell
180
GNU grep juga dapat mendukung pandangan ke depan & belakang positif & negatif: Untuk kasus Anda, perintahnya adalah:
echo "Here is a string"| grep -o -P '(?<=Here).*(?=string)'
$ echo 'Here is a string, and Here is another string.'| grep -oP '(?<=Here).*(?=string)'# Greedy match
is a string, and Here is another
$ echo 'Here is a string, and Here is another string.'| grep -oP '(?<=Here).*?(?=string)'# Non-greedy match (Notice the '?' after '*' in .*)
is a
is another
Perhatikan bahwa -Popsi GNU grep tidak ada dalam yang greptermasuk dalam * BSD, atau yang datang dengan SVR4 (Solaris, dll). Di FreeBSD, Anda dapat menginstal devel/pcreport yang termasukpcregrep , yang mendukung PCRE (dan lihat-depan / belakang). OSX versi lama menggunakan GNU grep, tetapi di OSX Mavericks, -Pberasal dari versi FreeBSD, yang tidak menyertakan opsi.
ghoti
1
Hai, Bagaimana cara mengekstrak konten yang berbeda saja?
Durgesh Suthar
4
Ini tidak berfungsi karena jika string akhir Anda "string" terjadi lebih dari satu kali, itu akan menjadi kejadian terakhir , bukan yang berikutnya kejadian .
Buttle Butkus
6
Dalam hal Here is a string a string, keduanya" is a " dan " is a string a "merupakan jawaban yang valid (abaikan tanda kutip), sesuai persyaratan pertanyaan. Tergantung pada Anda yang mana dari yang Anda inginkan dan kemudian jawabannya dapat berbeda. Bagaimanapun, untuk kebutuhan Anda, ini akan berhasil:echo "Here is a string a string" | grep -o -P '(?<=Here).*?(?=string)'
Jawaban Anda menjanjikan. Namun satu masalah. Bagaimana saya bisa mengekstraknya ke String yang terlihat pertama jika ada beberapa String di baris yang sama? Terima kasih
Mian Asbat Ahmad
@MianAsbatAhmad Anda ingin membuat *quantifier, antara Heredan String, tidak serakah (atau malas). Namun, jenis regex yang digunakan oleh sed tidak mendukung quantifiers malas ( ?segera setelah .*) menurut pertanyaan Stackoverflow ini . Biasanya untuk menerapkan quantifier malas, Anda hanya akan mencocokkan dengan segala sesuatu kecuali token yang tidak ingin Anda cocokkan, tetapi dalam hal ini, tidak hanya ada satu token, melainkan seluruh string String,.
mengapa metode ini sangat lambat? ketika melucuti halaman html besar menggunakan metode ini dibutuhkan sekitar 10 detik.
Adam Johns
@ AdamJohns, metode apa? Yang PCRE? PCRE cukup rumit untuk diurai, tetapi 10 detik tampak ekstrem. Jika Anda khawatir, saya sarankan Anda mengajukan pertanyaan termasuk kode contoh, dan lihat apa yang dikatakan para ahli.
ghoti
Saya pikir itu sangat lambat bagi saya karena memegang sumber file html yang sangat besar dalam suatu variabel. Ketika saya menulis konten ke file dan kemudian mengurai file kecepatannya meningkat secara dramatis.
Adam Johns
22
Melalui GNU awk,
$ echo "Here is a string"| awk -v FS="(Here|string)"'{print $2}'
is a
grep dengan dukungan parameter -P( perl-regexp ) \K, yang membantu membuang karakter yang sebelumnya cocok. Dalam kasus kami, string yang sebelumnya cocok Heresehingga dibuang dari hasil akhir.
$ echo "Here is a string"| grep -oP 'Here\K.*(?=string)'
is a
$ echo "Here is a string"| grep -oP 'Here\K(?:(?!string).)*'
is a
Jika Anda ingin hasilnya menjadi is amaka Anda bisa mencoba di bawah ini,
$ echo "Here is a string"| grep -oP 'Here\s*\K.*(?=\s+string)'
is a
$ echo "Here is a string"| grep -oP 'Here\s*\K(?:(?!\s+string).)*'
is a
Ini tidak berfungsi untuk :, echo "Here is a string dfdsf Here is a string" | awk -v FS="(Here|string)" '{print $2}'hanya mengembalikan is asebagai ganti is a is a@Avinash Raj
alper
20
Jika Anda memiliki file panjang dengan banyak multi-line ocurrences, ada baiknya untuk terlebih dahulu mencetak baris-baris angka:
Terima kasih! Ini adalah satu-satunya solusi yang bekerja dalam kasus saya (file teks berganda, daripada satu string tanpa jeda baris). Jelas, untuk memilikinya tanpa penomoran baris, -nopsi di catharus dihilangkan.
Jeffrey Lebowski
... dalam hal mana catdapat sepenuhnya dihilangkan; sedtahu cara membaca file atau input standar.
tripleee
9
Ini mungkin bekerja untuk Anda (sed GNU):
sed '/Here/!d;s//&\n/;s/.*\n//;:a;/String/bb;$!{n;ba};:b;s//\n&/;P;D' file
Ini menyajikan setiap representasi teks antara dua penanda (dalam hal ini Heredan String) pada baris baru dan mempertahankan baris baru dalam teks.
Semua solusi di atas memiliki kekurangan di mana string pencarian terakhir diulang di tempat lain dalam string. Saya menemukan yang terbaik untuk menulis fungsi bash.
function str_str {local str
str="${1#*${2}}"
str="${str%%$3*}"
echo -n "$str"}# test it ...
mystr="this is a string"
str_str "$mystr""this "" string"
$ echo "Here is a String"| sed 's/.*Here//; s/String.*//'
is a
Juga berfungsi
$ echo "Here is a StringHere is a String"| sed 's/.*Here//; s/String.*//'
is a
$ echo "Here is a StringHere is a StringHere is a StringHere is a String"| sed 's/.*Here//; s/String.*//'
is a
Ini menghilangkan string alih-alih menghasilkan sesuatu di antaranya. Coba hapus "Hello" dengan "is" di perintah sed dan itu akan menampilkan "Hello a"
Jonathan
1
Masalah. Pesan Claws Mail saya yang tersimpan dibungkus sebagai berikut, dan saya mencoba untuk mengekstrak baris Subjek:
Subject:[SLC38A9 lysosomal arginine sensor; mTORC1 pathway]Key molecular
link in major cell growth pathway:Findings point to new potential
therapeutic target in pancreatic cancer [mTORC1 Activator SLC38A9 IsRequired to EffluxEssentialAminoAcids from Lysosomes and UseProtein as
a Nutrient][Re:Nutrient sensor in key growth-regulating metabolic pathway
identified [Lysosomal amino acid transporter SLC38A9 signals arginine
sufficiency to mTORC1]]Message-ID:<20171019190902.18741771@VictoriasJourney.com>
[SLC38A9 lysosomal arginine sensor; mTORC1 pathway]Key molecular link in major cell growth pathway:Findings point to new potential therapeutic target in pancreatic cancer [mTORC1 Activator SLC38A9 IsRequired to EffluxEssentialAminoAcids from Lysosomes and UseProtein as a Nutrient][Re:Nutrient sensor in key growth-regulating metabolic pathway identified [Lysosomal amino acid transporter SLC38A9 signals arginine sufficiency to mTORC1]]
sed ':a;N;$!ba;s/\n/ /g' corpus/01| grep -o -P '(?<=Subject: ).*(?=Message-ID:)'
pemberian yang mana
[SLC38A9 lysosomal arginine sensor; mTORC1 pathway]Key molecular link in major cell growth pathway:Findings point to new potential therapeutic target in pancreatic cancer [mTORC1 Activator SLC38A9 IsRequired to EffluxEssentialAminoAcids from Lysosomes and UseProtein as a Nutrient][Re:Nutrient sensor in key growth-regulating metabolic pathway identified [Lysosomal amino acid transporter SLC38A9 signals arginine sufficiency to mTORC1]]
[SLC38A9 lysosomal arginine sensor; mTORC1 pathway]Key molecular link in major cell growth pathway:Findings point to new potential therapeutic target in pancreatic cancer [mTORC1 Activator SLC38A9 IsRequired to EffluxEssentialAminoAcids from Lysosomes and UseProtein as a Nutrient][Re:Nutrient sensor in key growth-regulating metabolic pathway identified [Lysosomal amino acid transporter SLC38A9 signals arginine sufficiency to mTORC1]]
Here is a Here String
? AtauI Hereby Dub Thee Sir Stringy
?sed
FAQ umum lainnya adalah "bagaimana saya bisa mengekstrak teks di antara baris tertentu"; ini adalah stackoverflow.com/questions/16643288/…Jawaban:
sumber
echo "Here is a one is a String" | sed -e 's/one is\(.*\)String/\1/'
. Jika Anda hanya ingin bagian antara "satu" dan "String", maka Anda perlu membuat regex cocok seluruh baris:sed -e 's/.*one is\(.*\)String.*/\1/'
. Selain itu,s/pattern/replacement/
ucapkan "gantikan 'penggantian' untuk 'pola' di setiap baris". Itu hanya akan mengubah apa pun yang cocok dengan "pola", jadi jika Anda ingin mengganti seluruh baris, Anda perlu membuat "pola" cocok dengan seluruh garis.Here is a String Here is a String
GNU grep juga dapat mendukung pandangan ke depan & belakang positif & negatif: Untuk kasus Anda, perintahnya adalah:
Jika ada beberapa kejadian
Here
danstring
, Anda dapat memilih apakah Anda ingin mencocokkan dari yang pertamaHere
dan terakhirstring
atau mencocokkannya satu per satu. Dalam hal regex, itu disebut sebagai pertandingan serakah (kasus pertama) atau pertandingan tidak serakah (kasus kedua)sumber
-P
opsi GNU grep tidak ada dalam yanggrep
termasuk dalam * BSD, atau yang datang dengan SVR4 (Solaris, dll). Di FreeBSD, Anda dapat menginstaldevel/pcre
port yang termasukpcregrep
, yang mendukung PCRE (dan lihat-depan / belakang). OSX versi lama menggunakan GNU grep, tetapi di OSX Mavericks,-P
berasal dari versi FreeBSD, yang tidak menyertakan opsi.Here is a string a string
, keduanya" is a "
dan" is a string a "
merupakan jawaban yang valid (abaikan tanda kutip), sesuai persyaratan pertanyaan. Tergantung pada Anda yang mana dari yang Anda inginkan dan kemudian jawabannya dapat berbeda. Bagaimanapun, untuk kebutuhan Anda, ini akan berhasil:echo "Here is a string a string" | grep -o -P '(?<=Here).*?(?=string)'
echo $'Here is \na string' | grep -zoP '(?<=Here)(?s).*(?=string)'
Jawaban yang diterima tidak menghapus teks yang bisa sebelum
Here
atau sesudahString
. Ini akan:Perbedaan utama adalah penambahan
.*
segera sebelumHere
dan sesudahString
.sumber
*
quantifier, antaraHere
danString
, tidak serakah (atau malas). Namun, jenis regex yang digunakan oleh sed tidak mendukung quantifiers malas (?
segera setelah.*
) menurut pertanyaan Stackoverflow ini . Biasanya untuk menerapkan quantifier malas, Anda hanya akan mencocokkan dengan segala sesuatu kecuali token yang tidak ingin Anda cocokkan, tetapi dalam hal ini, tidak hanya ada satu token, melainkan seluruh stringString
,..
tidak cocok dengan jeda baris. Jika Anda ingin mencocokkan jeda baris, Anda dapat menggantinya.
dengan sesuatu seperti[\s\s]
.Anda dapat menghapus string di Bash saja:
Dan jika Anda memiliki grep GNU yang mencakup PCRE , Anda dapat menggunakan pernyataan selebar nol:
sumber
Melalui GNU awk,
grep dengan dukungan parameter
-P
( perl-regexp )\K
, yang membantu membuang karakter yang sebelumnya cocok. Dalam kasus kami, string yang sebelumnya cocokHere
sehingga dibuang dari hasil akhir.Jika Anda ingin hasilnya menjadi
is a
maka Anda bisa mencoba di bawah ini,sumber
echo "Here is a string dfdsf Here is a string" | awk -v FS="(Here|string)" '{print $2}'
hanya mengembalikanis a
sebagai gantiis a is a
@Avinash RajJika Anda memiliki file panjang dengan banyak multi-line ocurrences, ada baiknya untuk terlebih dahulu mencetak baris-baris angka:
sumber
-n
opsi dicat
harus dihilangkan.cat
dapat sepenuhnya dihilangkan;sed
tahu cara membaca file atau input standar.Ini mungkin bekerja untuk Anda (sed GNU):
Ini menyajikan setiap representasi teks antara dua penanda (dalam hal ini
Here
danString
) pada baris baru dan mempertahankan baris baru dalam teks.sumber
Semua solusi di atas memiliki kekurangan di mana string pencarian terakhir diulang di tempat lain dalam string. Saya menemukan yang terbaik untuk menulis fungsi bash.
sumber
Anda dapat menggunakan perintah dua s
Juga berfungsi
sumber
Untuk memahami
sed
perintah, kita harus membangunnya langkah demi langkah.Ini teks asli Anda
Mari kita coba hapus
Here
string dengans
opsi ubstition dised
Pada titik ini, saya percaya Anda akan dapat menghapus
String
jugaTapi ini bukan output yang Anda inginkan.
Untuk menggabungkan dua perintah sed, gunakan
-e
opsiSemoga ini membantu
sumber
Anda dapat menggunakan
\1
(lihat http://www.grymoire.com/Unix/Sed.html#uh-4 ):Konten yang ada di dalam kurung akan disimpan sebagai
\1
.sumber
Masalah. Pesan Claws Mail saya yang tersimpan dibungkus sebagai berikut, dan saya mencoba untuk mengekstrak baris Subjek:
Per A2 di utas ini, Bagaimana cara menggunakan sed / grep untuk mengekstrak teks antara dua kata? ekspresi pertama, di bawah, "berfungsi" selama teks yang cocok tidak mengandung baris baru:
Namun, walaupun telah mencoba banyak varian (
.+?; /s; ...
), saya tidak bisa membuatnya berfungsi:Solusi 1.
Per Ekstrak teks antara dua string pada baris yang berbeda
pemberian yang mana
Solusi 2. *
Per Bagaimana saya bisa mengganti baris baru (\ n) menggunakan sed?
akan mengganti baris baru dengan spasi.
Chaining itu dengan A2 di Cara menggunakan sed / grep untuk mengekstrak teks antara dua kata? , kita mendapatkan:
pemberian yang mana
Varian ini menghilangkan spasi ganda:
memberi
sumber