Hari ini saya harus menghapus 1131 byte pertama dari file teks / biner campuran 800MB, sebuah subversi sampah yang disaring. Saya meretas untuk repositori baru. Apa cara terbaik untuk melakukan ini?
Untuk mulai dengan saya mencoba
dd bs=1 skip=1131 if=filtered.dump of=trimmed.dump
tetapi setelah melewati ini menyalin sisa file satu byte pada satu waktu, yaitu sangat lambat. Pada akhirnya saya berhasil saya perlu 405 byte untuk membulatkan ini hingga tiga blok 512 yang bisa saya lewati
dd if=/dev/zero of=405zeros bs=1 count=405
cat 405zeros filtered.dump | dd bs=512 skip=3 of=trimmed.dump
yang selesai cukup cepat tetapi pasti ada cara yang lebih sederhana / lebih baik? Apakah ada alat lain yang saya lupa? Terima kasih!
dd
adalah alat yang tepat untuk pekerjaan itu - sepertinya Anda datang dengan solusi yang bagus dan elegan untuk masalah Anda.Jawaban:
Anda dapat beralih bs dan melewati opsi:
Dengan cara ini operasi dapat mengambil manfaat dari blok yang lebih besar.
Jika tidak, Anda bisa mencoba dengan tail (walaupun tidak aman untuk menggunakannya dengan file biner):
Akhirnya, Anda dapat menggunakan instance 3 dd untuk menulis sesuatu seperti ini:
di mana dd pertama mencetak output standarnya difilter.dump; yang kedua hanya membaca 1131 byte dan membuangnya; kemudian, yang terakhir membaca dari input standarnya byte yang tersisa dari filtered.dump dan menuliskannya ke trimmed.dump.
sumber
bs=1131 skip=1
: - /Tidak yakin kapan
skip_bytes
ditambahkan, tetapi untuk melewati 11 byte pertama yang Anda miliki:Di mana
iflag=skip_bytes
memberitahu dd untuk menginterpretasikan nilaiskip
opsi sebagai byte alih-alih blok, membuatnya langsung.sumber
iflag=skip_bytes skip=1234 bs=1M
Anda dapat menggunakan sub-shell dan dua
dd
panggilan seperti ini:sumber
Jika filesystem dan kernel Linux mendukungnya maka Anda bisa mencoba
fallocate
jika Anda ingin membuat perubahan di tempat: dalam kasus terbaik tidak ada data IO sama sekali:di mana
<magic>
tergantung pada sistem file, versi Linux, dan jenis file (FALLOC_FL_COLLAPSE_RANGE
atauFALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE
dapat digunakan secara internal ).sumber
Anda harus menggunakan
count=0
- itu sesederhanalseek()
mungkin.Seperti ini:
dd
akanlseek()
deskriptor file input ke offset 1131 byte, dan kemudiancat
hanya akan menyalin apa pun yang tersisa ke output.sumber
Namun cara lain untuk menghapus byte utama dari file (tanpa menggunakan
dd
sama sekali) adalah dengan menggunakanxxd
dan masingsed
-tail
masing.sumber
@maxschlepzig meminta liner online. Berikut ini satu perl. Dibutuhkan 2 argumen: Dari byte dan panjang. File input harus diberikan oleh '<' dan output akan berada di stdout:
Jika panjangnya lebih besar dari file, sisa file akan disalin.
Di sistem saya ini memberikan 3,5 GB / s.
sumber
dd
tidak menjamin pembacaan penuh. Coba: ya | dd bs = 1024k hitung = 10 | wc unix.stackexchange.com/questions/17295/…