Bagaimana saya bisa menghapus semuanya sampai suatu pola dan semua setelah pola lain dari suatu garis?


16

Dalam file berikut:

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut eu metus id lectus vestibulum ultrices. Maecenas rhoncus.

Saya ingin menghapus semuanya sebelum consectetuerdan sesudahnya elit.

Output yang saya inginkan:

consectetuer adipiscing elit.

Bagaimana saya bisa melakukan ini?


2
Perintahnya bisa sed. Bisa juga perl, atau bahkan bash murni.
muru

@manuel Jika salah satu dari jawaban ini menyelesaikan masalah Anda, mohon luangkan waktu dan terima dengan mengklik tanda centang di sebelah kiri. Itu akan menandai pertanyaan sebagai dijawab dan cara terima kasih diungkapkan di situs Stack Exchange.
terdon

Jawaban:


27

Saya akan menggunakan sed

sed 's/^.*\(consectetuer.*elit\).*$/\1/' file

Mendekode sed s / find / replace / syntax:

  • s/^.*- gantikan mulai dari awal baris ( ^) diikuti oleh apa saja ( .*) hingga ...
  • \( - mulai blok bernama
  • consectetuer.*elit\.- cocok dengan kata pertama, semuanya ( .*) hingga kata terakhir (dalam hal ini, termasuk titik trailing (lolos)) yang ingin Anda cocokkan
  • \) - akhiri blok bernama
  • cocokkan semua yang lain ( .*) hingga akhir baris ( $)
  • / - akhiri bagian cari pengganti
  • \1- ganti dengan blok nama antara yang \(di \)atas dan yang di atas
  • / - akhiri penggantian

1
Jawaban yang bagus, tetapi Anda tidak perlu ^atau $karena sed akan mencoba dan menemukan pasangan yang paling lama. Anda juga mungkin telah melewatkan titik setelahnya elit, Anda bisa memasukkannya \.jika perlu.
asoundmove

2
@asoundmove Tangkapan yang bagus di trailing dot pada "elit." - Anda memiliki mata yang cukup tajam !. Saya telah memperbarui jawaban saya untuk memasukkan titik yang lolos dalam pola. Anda juga benar bahwa ^dan $tidak perlu - saya meninggalkan mereka di sana sebagai penanya mencatat (awalnya) bahwa dia sedikit pemula dan ini mungkin membantu dalam konteks lain.
MikeV

Saya selalu menyalin solusi yang dilekatkan dan meretasnya agar sesuai dengan kebutuhan saya, tetapi berkat jawaban ini saya merasa seperti saya benar-benar memahaminya sekarang. Jawaban bagus
Tyler

6

Jika setiap baris berisi pola awal dan akhir maka cara termudah untuk melakukannya adalah dengan grep. Alih-alih menghapus awal dan akhir setiap baris, Anda cukup menampilkan konten di antara kedua pola. The -opilihan di GNU grepoutput hanya pertandingan:

grep -o 'consectetuer.*elit' file

Catatan: seperti yang disebutkan, ini hanya berfungsi jika setiap baris dalam file dapat diuraikan dengan cara ini. Kemudian lagi, itu 80% dari semua kasus penggunaan khas.


1

Dua untuk loop di AWK:

$ awk '{for(i=1;i<=NF;i++) {if ($i == "consectetuer") beginning=i; if($i== "elit.") ending=i }; for (j=beginning;j<=ending;j++) printf $j" ";printf "\n"   }' file.txt 
consectetuer adipiscing elit.

AWK's gsub:

$ awk '{gsub(/^.*consectetuer/,"consectetuer"); gsub(/elit.*$/,"elit.");print}' file.txt
consectetuer adipiscing elit.

1

Cara Perl. Ini pada dasarnya sama dengan jawaban MikeVsed :

perl -pe 's/.*(consectetuer.*elit).*./$1/' file

The -pberarti "mencetak setiap baris setelah menerapkan script yang diberikan dengan -e". The s/foo/bar/adalah operator substitusi; itu akan diganti foodengan bar. Tanda kurung menangkap pola dan mari kita gunakan dalam penggantian. Pola yang ditangkap pertama adalah $1, yang kedua $2dan seterusnya.

Jadi, perintah akan mencocokkan semuanya hingga consectetuer( .*consectetuer), lalu semuanya sampai elit( .*elit) dan kemudian yang lainnya sampai akhir baris ( .*) dan akan menggantinya dengan pola yang ditangkap.


1

Saya tidak yakin mengapa judul pertanyaan ini telah diedit " dari file " ke " dari satu baris " sementara OP tidak mengecualikan kemungkinan di beberapa baris meskipun contohnya tampaknya hanya satu baris. Apa pun itu, mungkin bermanfaat untuk memberikan solusi beberapa jalur di sini.

Ini bekerja untuk garis silang:

from1=consectetuer; to2=elit; a="$(cat file)"; a="$(echo "${a#*"$from1"}")"; echo "$from1${a%%"$to2"*}$to2"

Contoh:

[xiaobai@xiaobai tmp]$ cat file
1
abc consectetuer lsl

home

def elit dd
2 consectetuer ABC elit
[xiaobai@xiaobai tmp]$ from1=consectetuer; to2=elit; a="$(cat file)"; a="$(echo "${a#*"$from1"}")"; echo "$from1${a%%"$to2"*}$to2"
consectetuer lsl

home

def elit
[xiaobai@xiaobai tmp]$ 

referensi: Ekspansi Parameter Shell


1
Itu sempurna!
Clément
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.