GNU/Linux >> Belajar Linux >  >> Linux

Bagaimana cara menghapus garis yang muncul pada file B dari file A lainnya?

Jika file diurutkan (ada dalam contoh Anda):

comm -23 file1 file2

-23 menekan baris yang ada di kedua file, atau hanya di file 2. Jika file tidak diurutkan, kirimkan melalui sort pertama...

Lihat halaman manualnya di sini


awk untuk menyelamatkan!

Solusi ini tidak memerlukan input yang diurutkan. Anda harus menyediakan fileB terlebih dahulu.

awk 'NR==FNR{a[$0];next} !($0 in a)' fileB fileA

kembali

A
C

Bagaimana cara kerjanya?

NR==FNR{a[$0];next} idiom adalah untuk menyimpan file pertama dalam larik asosiatif sebagai kunci untuk pengujian "berisi" selanjutnya.

NR==FNR sedang memeriksa apakah kami memindai file pertama, dengan penghitung baris (NR) global sama dengan penghitung baris file (FNR) saat ini.

a[$0] menambahkan baris saat ini ke array asosiatif sebagai kunci, perhatikan bahwa ini berperilaku seperti satu set, di mana tidak akan ada nilai duplikat (kunci)

!($0 in a) kita sekarang berada di file berikutnya, in adalah tes berisi, di sini memeriksa apakah baris saat ini ada di set yang kita isi di langkah pertama dari file pertama, ! meniadakan kondisi tersebut. Apa yang hilang di sini adalah tindakannya, yang secara default adalah {print} dan biasanya tidak ditulis secara eksplisit.

Perhatikan bahwa ini sekarang dapat digunakan untuk menghapus kata-kata yang masuk daftar hitam.

$ awk '...' badwords allwords > goodwords

dengan sedikit perubahan dapat membersihkan beberapa daftar dan membuat versi yang dibersihkan.

$ awk 'NR==FNR{a[$0];next} !($0 in a){print > FILENAME".clean"}' bad file1 file2 file3 ...

Cara lain untuk melakukan hal yang sama (juga membutuhkan masukan yang diurutkan):

join -v 1 fileA fileB

Di Bash, jika file tidak diurutkan sebelumnya:

join -v 1 <(sort fileA) <(sort fileB)

grep -Fvxf <lines-to-remove> <all-lines>

  • berfungsi pada file yang tidak diurutkan (tidak seperti comm )
  • menjaga ketertiban
  • adalah POSIX

Contoh:

cat <<EOF > A
b
1
a
0
01
b
1
EOF

cat <<EOF > B
0
1
EOF

grep -Fvxf B A

Keluaran:

b
a
01
b

Penjelasan:

  • -F :gunakan string literal alih-alih BRE default
  • -x :hanya pertimbangkan kecocokan yang cocok dengan seluruh baris
  • -v :cetak tidak cocok
  • -f file :ambil pola dari file yang diberikan

Metode ini lebih lambat pada file yang sudah diurutkan sebelumnya daripada metode lain, karena lebih umum. Jika kecepatan juga penting, lihat:Cara cepat menemukan baris di satu file yang tidak ada di file lain?

Inilah otomatisasi bash cepat untuk operasi in-line:

remove-lines() (
  remove_lines="$1"
  all_lines="$2"
  tmp_file="$(mktemp)"
  grep -Fvxf "$remove_lines" "$all_lines" > "$tmp_file"
  mv "$tmp_file" "$all_lines"
)

GitHub upstream.

penggunaan:

remove-lines lines-to-remove remove-from-this-file

Lihat juga:https://unix.stackexchange.com/questions/28158/is-there-a-tool-to-get-the-lines-in-one-file-that-are-not-in-another


Linux
  1. Bagaimana Menghapus Baris Kosong Dari File (termasuk Tab Dan Spasi)?

  2. Pilih Baris Dari File Teks Yang Memiliki Id Terdaftar Di File Lain?

  3. Bagaimana Cara Menghapus Bom Dari File Utf-8?

  1. Bagaimana Cara Memindahkan File Dari Satu Akun Pengguna Ke Akun Pengguna Lain Di Komputer Yang Sama?

  2. Bagaimana cara menghapus file dari tempat sampah di Ubuntu?

  3. Bagaimana cara menghapus perangkat cache dari bcache?

  1. Bagaimana cara menghapus baris baru dari file teks?

  2. Bagaimana cara menggunakan baris file sebagai argumen perintah?

  3. Bagaimana cara menghapus X byte dari akhir file besar tanpa membaca seluruh file?