Saya punya dua file, file1
dan file2
.
Isi sampel file1
adalah:
A B
C D
E F
G H
dan isinya file2
seperti:
A B
few other lines
E F
few more other lines
A B
C D
E F
G H
few more other lines
G H
Jadi saya ingin mencari seluruh blok file1
konten file2
hanya. Ini berarti output harus hanya berisi baris-baris ini:
A B
C D
E F
G H
harap dicatat bahwa: - hanya garis-garis yang menyatu, harus menjadi bagian dari output.
shell-script
text-processing
awk
sed
sachin
sumber
sumber
file1
dan tidak ada yang lain, cukup gunakancat file1
.Jawaban:
grep
cukup bodoh ketika datang ke pola multiline, tetapi menerjemahkan semua karakter baris baru\n
dari pola dan teks untuk mencari ke dalam karakter NUL\0
sebelum membandingkannya memperbaikinya. Menerjemahkan\0
kembali ke output\n
jelas juga diperlukan.Inilah perintah Anda, dengan asumsi bahwa itu
file1
berisi pola yang ingin Anda carifile2
:Contoh output untuk file yang Anda berikan:
Penjelasan:
<(tr '\n' '\0' < file1)
membuat FIFO / bernama pipe / objek file-like sementara yang samafile1
, tetapi dengan semua karakter baris baru diterjemahkan ke karakter NUL.<(tr '\n' '\0' < file2)
melakukan hal yang sama, tetapi untukfile2
.grep -f PATTERN_FILE INPUT_FILE
mencari pola dariPATTERN_FILE
dalamINPUT_FILE
.-a
benderagrep
memungkinkan pencocokan pada file biner. Ini diperlukan karena jika tidak maka akan melewatkan file yang berisi karakter yang tidak dapat dicetak seperti\0
.-o
benderagrep
merek itu hanya mencetak urutan pencocokan, bukan seluruh baris di mana telah ditemukan.| tr '\0' '\n'
menerjemahkan semua karakter NUL dari output perintah di sisi kiri kembali ke karakter baris baru.sumber
Berikut ini adalah canggung, tetapi bekerja dengan GNU
awk
:sumber
Hanya untuk bersenang-senang di bash murni
sumber
Berikut ini sedikit lebih elegan
grep
+perl
:Namun, ada satu tangkapan besar. Jika ada baris baru Trailing di
file1
, pola tidak akan benar, dengan kata lain:A B\nC D\nE F\nG H\n\n
.(Terima kasih khusus @terdon untuk memberikan bagian perl)
Seperti yang dicatat oleh costas, seseorang dapat menggunakan
perl -0pe 's/\n(\n+$)?/\\n/g'
menggantikanperl
perintah lain untuk menghindari baris baru yang tertinggal difile1.txt
sumber
perl -0pe 's/\n(\n+$)?/\\n/g'
. Tanpa-0
itug
modifikator regex tambahan.Saya tidak terlalu yakin apa yang Anda inginkan, tetapi mudah dilakukan dengan bahasa yang tidak berorientasi garis (terutama jika kedua file dapat dibaca ke dalam memori). Inilah skrip python yang akan memberi tahu Anda berapa banyak kecocokan yang ada.
Anda ingin mencetak
file1
sesering mungkin? Ganti baris terakhir dengan ini:Anda bisa mengemas semuanya menjadi panggilan baris perintah atau alias, jika Anda benar-benar ingin:
sumber
hasilnya adalah semua file dengan teks yang sama persis
sumber
Berikut adalah pendekatan lain menggunakan python (diuji dengan
python3 3.5.2
, tanpa keluhan daripylint3 1.5.6
):Penanganan argumen command line via
sys.argv
diakui sederhana. Anda bisa melakukan banyak hal lain dengan nilai pengembalianfinder
pada duamemoryview
objek yang Anda lewati, selain meneruskannyatuple
. SetiapSRE_Match
item yang dihasilkan oleh iterator yang dikembalikan olehfinder
memiliki berbagai metode, sampel yang dirangkum dalamprint
output (span
, misalnya, memberitahu rentang byte dari setiap pertandingan).sumber