Input file1 adalah:
dog 123 4335
cat 13123 23424
deer 2131 213132
bear 2313 21313
Saya memberikan kecocokan pola dari dalam other file
(seperti dog 123 4335
dari file2).
Saya cocok dengan pola garis itu dog 123 4335
dan setelah mencetak semua garis tanpa garis cocok keluaran saya adalah:
cat 13123 23424
deer 2131 213132
bear 2313 21313
Jika hanya menggunakan tanpa alamat jalur hanya menggunakan pola, misalnya 1s
bagaimana cara mencocokkan dan mencetak garis?
text-processing
sed
grep
loganaayahee
sumber
sumber
Jawaban:
Dengan asumsi Anda ingin mencocokkan keseluruhan garis dengan pola Anda, dengan GNU
sed
, ini berfungsi:Setara standar:
Dengan input berikut (
infile
):Outputnya adalah:
Penjelasan:
/^dog 123 4335$/
mencari pola yang diinginkan.:a; n; p; ba;
adalah loop yang mengambil baris baru dari input (n
), mencetaknya (p
), dan bercabang kembali ke label a:a; ...; ba;
.Memperbarui
Inilah jawaban yang mendekati kebutuhan Anda, yaitu pola di file2, yang diambil dari file1:
Grep dan cut yang disematkan menemukan baris pertama yang berisi pola dari file2, nomor baris ini ditambah satu diteruskan ke ekor, plus satu ada di sana untuk melewati garis dengan pola.
Jika Anda ingin memulai dari pertandingan terakhir alih-alih pertandingan pertama adalah:
Perhatikan bahwa tidak semua versi ekor mendukung notasi plus.
sumber
sed -n '/^dog 123 4335$/ { :a; p; n; ba; }' infile
(dengan p dan n diaktifkan) berhasil memasukkan garis yang cocok juga.Jika Anda memiliki file yang cukup pendek
grep
saja mungkin berfungsi:5000 hanya dugaan saya di "cukup pendek", karena
grep
menemukan kecocokan pertama dan output bersama dengan 5000 baris berikutnya (file tidak perlu memiliki banyak). Jika Anda tidak ingin pertandingan itu sendiri, Anda harus memotongnya, misJika Anda tidak menginginkan yang pertama, tetapi kecocokan terakhir sebagai pembatas, Anda dapat menggunakan ini:
Baris ini membaca
animals.txt
dalam urutan terbalik dari baris dan output hingga dan termasuk baris dengandog 123 4335
dan kemudian berbalik lagi untuk mengembalikan urutan yang tepat.Sekali lagi, jika Anda tidak membutuhkan kecocokan dalam hasilnya, tambahkan ekor. (Anda juga bisa menyulitkan ekspresi sed untuk membuang buffernya sebelum berhenti.)
sumber
Dalam prakteknya saya mungkin akan menggunakan jawaban Aet3miirah sebagian besar waktu dan jawaban alexey luar biasa ketika ingin menavigasi melalui garis (juga, itu juga berfungsi dengan
less
). OTOH, saya sangat menyukai pendekatan lain (yang merupakan jawaban terbalik dari Gilles :Ketika dipanggil dengan
-n
flag,sed
tidak mencetak secara default garis yang diprosesnya lagi. Kemudian kami menggunakan formulir 2-alamat yang mengatakan untuk menerapkan perintah dari baris yang cocok/dog 123 4335/
sampai akhir file (diwakili oleh$
). Perintah yang dimaksud adalahp
, yang mencetak baris saat ini. Jadi, ini berarti "cetak semua garis dari yang cocok/dog 123 4335/
sampai akhir."sumber
dog
garis yang tidak diinginkan di sini.sed -n '/dog 123 4335/,$p' | tail -n +2
akan menghapus pertandingan jugaJika Anda perlu membaca pola dari file, gantikan dengan perintah sed. Jika file berisi pola sed:
Jika file berisi string literal yang harus dicari, kutip semua karakter khusus. Saya menganggap file tersebut berisi satu baris.
Jika Anda ingin kecocokan menjadi seluruh baris, bukan hanya substring, bungkus pola
^…$
.sumber
sed
punya0,/dog.../d
untuk itu.$ more +/"dog 123 4335" file1
sumber
less
.tac
.+
digantikan oleh-p
dalam POSIX 7: pubs.opengroup.org/onlinepubs/9699919799/utilities/more.html tetapi belum diimplementasikan di util-linux 2.20.1. Dan ini juga mencetakskipping..
dan beberapa baris baru (untuk stderr saya harapkan, jadi mungkin baik-baik saja).Dengan
awk
:sumber
Salah satu cara menggunakan awk:
di mana file2 berisi pola pencarian Anda. Pertama, semua isi file2 disimpan dalam array "a". Ketika file1 diproses, setiap baris diperiksa terhadap array, dan dicetak hanya jika tidak ada.
sumber
Jika input adalah file biasa yang dapat dibaca :
Dengan GNU
grep
:Dengan
sed
:GNU
grep
bernama w /-m
opsi akan berhenti input pada pertandingan - dan itu akan meninggalkan input (lseekable) fd segera setelah titik itu menemukan pertandingan terakhirnya. Jadi memanggilgrep
w /-m1
menemukan kejadian pertama pola dalam file, dan daun masukan offset tepat pada tempat yang tepat untukcat
untuk menulis segala sesuatu mengikuti pertandingan pertama pola dalam file ke stdout.Bahkan tanpa GNU
grep
Anda dapat melakukan hal yang sama persis dengan kompatibel POSIXsed
- ketikased
q
digunakan ditentukan untuk membiarkan input offsetnya tetap di tempatnya. GNUsed
tidak memenuhi standar dengan cara ini, dan karenanya di atas kemungkinan tidak akan bekerja dengan GNUsed
kecuali jika Anda menyebutnya dengan-u
saklarnya.sumber
sed
berbagi aliran yang diperlihatkan di sini tidak secara khusus (meskipun, ya, standar yang dirujuk tidak secara khusus contohsed
sebagai utilitas yang mampu) dari alur kerja bentuk-bebas dan kondisional yang ditunjukkan. terutama, semua utilitas standar dimaksudkan dan ditentukan untuk dengan demikian bekerja sama dan berbagi posisi kursor dari aliran input tanpa membuat proses berikutnya gagal bagi pembaca berikutnya.grep -q
harus melakukan ini; diamgrep
- diam akan kembali segera setelah ditemukan kecocokan dalam input, dan sisa input tidak boleh, secara standar, dikonsumsi secara default.Jawaban saya untuk pertanyaan dalam subjek, tanpa menyimpan pola dalam file kedua. Ini file pengujian saya:
GNU sed:
Perl:
Varian Perl dengan pola dalam file:
sumber
Dengan
ed
:Ini mengirimkan satu
p
perintah rintisan ke ed dalam string di sini; perintah cetak dibatasi dalam kisaran satu setelah (+1
)dog 123 4335
kecocokan hingga akhir file ($
).sumber
Jika Anda tidak keberatan dengan pembuatan file sementara, dan sudah
csplit
tersedia, ini berfungsi:Catatan
file1
adalah file input danfile2
file pola (seperti yang dinyatakan dalam pertanyaan).Bentuk panjang dari perintah di atas adalah:
yaitu,
csplit
tanpaprefix
tanda di atas akan membuat filexx00
(awalan sedangxx
, dan akhiran sedang00
). Dengan bendera di atas itu menciptakan filefile1_00
. Tanpaquiet
flag, ia mencetak ukuran file output (ukuran file yang dihasilkan).sumber
Karena awk tidak dilarang secara tegas, inilah penawaran saya dengan asumsi 'kucing' adalah pasangannya.
sumber
Cara lain untuk menjelaskannya adalah "bagaimana menghapus semua baris dari baris pertama hingga yang cocok (termasuk)", dan ini dapat
sed
ditulis sebagai:sumber
sed -e '0,/MATCH PATTERN/d'
lalu bagaimana?