dd: çoklu giriş dosyaları


14

İki dosyadan parçalar birleştirmek gerekiyor:

tüm dosyaları birleştirmeye ihtiyacım olsaydı,

cat file1 file2 > output

Ancak ilk dosyadan ilk 1MB'yi atlamam gerekiyor ve ikinci dosyadan sadece 10 MB istiyorum. Kulağa iş gibi geliyor dd.

dd if=file1 bs=1M count=99 skip=1 of=temp1
dd if=file2 bs=1M count=10 of=temp2
cat temp1 temp2 > final_output

Bunu tek adımda yapma imkanı var mı? yani, ara sonuçları kaydetmeye gerek kalmadan? İçinde birden fazla girdi dosyası kullanabilir miyim dd?

Yanıtlar:


21

dd stdout'a da yazabilir.

( dd if=file1 bs=1M count=99 skip=1
  dd if=file2 bs=1M count=10  ) > final_output

Bu muhtemelen en iyi yoldur. Çıktı dosyası kapatılmadı / yeniden açılmadı (olduğu gibi oflag=append conv=notrunc), bu nedenle gecikmeli ayırma (XFS gibi) yapan dosya sistemlerinin, daha fazla şey olduğunda dosyanın yazılmasına karar vermesi en az muhtemeldir.
Peter Cordes

@PeterCordes bu iyi bir nokta, ancak ddistenmediği sürece sync, gecikmiş ayırma hemen devreye girmemelidir (bellek sıkı olmadığı sürece, bu durumda hiçbir yöntem ayırmayı ertelemeyecektir).
Stephen Kitt

@StephenKitt: Muhtemelen haklısın. XFS'nin spekülatif ön yerleşimini , özellikle kapat / yeniden aç erişim şablonunu (bazen günlük dosyaları için görülür) algılaması gerektiğini düşünüyordum.
Peter Cordes

3
Bir alt kabuktaki son komut için çatalı optimize etmeyen bashve gibi kabuklarda, alt kabuğu mkshbir komut grubuyla değiştirerek biraz daha verimli hale getirebilirsiniz. Diğer mermiler için önemli değil ve alt kabuk yaklaşımı, kabuğun stdout'u kaydetmesi ve geri yüklemesi gerekmediğinden biraz daha verimli olabilir.
Stéphane Chazelas

10

Tek bir ddçağrıda birden çok dosyayı kolayca okuyabileceğinizi sanmıyorum , ancak çıktı dosyasını birkaç adımda oluşturabilirsiniz:

dd if=file1 bs=1M count=99 skip=1 of=final_output
dd if=file2 bs=1M count=10 of=final_output oflag=append conv=notrunc

Her iki belirtmek gerekir conv=notruncve oflag=append. Birincisi çıktıyı kesmekten kaçınır, ikincisi mevcut dosyanın sonundan yazmaya başlar.


8

Akılda Ayı ddham arayüzüdür read(), write()ve lseek()sistem çağrısı. Yalnızca normal dosyalardan veri parçalarını ayıklamak, aygıtları ve bazı karakter aygıtlarını (gibi /dev/urandom) ayıklamak için güvenilir bir şekilde kullanabilirsiniz ; bu, dosyanın sonuna ulaşılmadığı sürece dosyalarının read(buf, size)döndürüleceği garantilidir size.

Borular, soketler ve çoğu karakter cihazı (ttys gibi) için, read()1 boyutunda olmadıkça veya GNU dduzantısını kullanmadığınız sürece böyle bir garantiniz yoktur iflag=fullblock.

Bu yüzden ya:

{
  gdd < file1 bs=1M iflag=fullblock count=99 skip=1
  gdd < file2 bs=1M iflag=fullblock count=10
} > final_output

Veya:

M=1048576
{
  dd < file1 bs=1 count="$((99*M))" skip="$M"
  dd < file2 bs=1 count="$((10*M))"
} > final_output

Veya aşağıdaki gibi bir arama operatörü için yerleşik desteğe sahip kabuklarla ksh93:

M=1048576
{
  command /opt/ast/bin/head -c "$((99*M))" < file1 <#((M))
  command /opt/ast/bin/head -c "$((10*M))" < file2
}

Veya zsh( headburadaki -cseçeneği desteklediğini varsayarak ):

zmodload zsh/system &&
{
  sysseek 1048576 && head -c 99M &&
  head -c 10M < file2
} < file1 > final_output

Alıntılara gerçekten ihtiyacınız var mı? Sonuç her zaman tamsayı olmaz mı?
Steven Penny

@StevenPenny, genişlemeyi belirtilmemiş olarak bırakmak, kabuktan ayrılmasını ve burada herhangi bir anlam ifade etmeyeceğini istiyor. Şu anki değeri üzerinde yapılan bölünmüş kısım $IFS. Bu, değişkenin / genişlemenin içeriğinden bağımsız olarak. Ayrıca bkz . Bash / POSIX mermilerinde bir değişken teklif etmeyi unutmanın güvenlik sonuçları
Stéphane Chazelas

@ Stéphane Chazelas - ilk örnekte, gddyerine kullanıyorsunuz dd. Bu bir yazım hatası mı, yoksa kasıtlı mı?
Martin Vegter

3

Bir bash izmiyle ve işlevsel olarak " kedinin yararsız kullanımı " ile, ancak OP'nin sözdizimine en yakın olanı:

cat <(dd if=file1 bs=1M count=99 skip=1) \
    <(dd if=file2 bs=1M count=10) \
   > final_output

(Bununla birlikte, Stephen Kitt'in cevabı mümkün olan en etkili yöntem gibi görünüyor .)


3
Açıkçası, <(...)bir olduğunu kshism hem zshve bashkopyalanamaz.
Stéphane Chazelas
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.