2011-11-09 22 views
16

İki yüzlü bir dosyam var; bu dosya, hexdump ve birkaç awk ve sed komutlarını kullanarak normal bir dosyaya dönüştürebiliyorum.Bir dosyayı birden çok dosyaya bölünmüş desene göre

$cat temp 
3d3d01f87347545002f1d5b2be4ee4d700010100018000cc57e5820000000000000000000 
000000087d3f513000000000000000000000000000000000001001001010f000000000026 
58783100b354c52658783100b43d3d0000ad6413400103231665f301010b9130194899f2f 
fffffffffff02007c00dc015800a040402802f1d5b2b8ca5674504f433031000000000004 
6363070000000000000000000000000065450000b4fb6b4000393d3d1116cdcc57e58287d 
3f55285a1084b 

geçici dosya sık tekrarlamayın birkaç göz yakalayıcı (3d3d) var - çıktı dosyası şuna benzer. Onlar yeni bir ikili kaydın başlangıcını gösterir. Dosyayı bu göz alıcılara göre ayırmam gerek.

İstenilen çıktım birden fazla dosyaya sahip olmaktır (geçici dosyamdaki göz alıcıların sayısına bağlı olarak).

Yani benim çıkış böyle bir şey olmazdı - bu sizin temp dosya veya değil tek bir çizgi halinde

$cat temp1 
3d3d01f87347545002f1d5b2be4ee4d700010100018000cc57e582000000000000000 
0000000000087d3f513000000000000000000000000000000000001001001010f00000000 
002658783100b354c52658783100b4 

$cat temp2 
3d3d0000ad6413400103231665f301010b9130194899f2ffffffffffff02007c00dc0 
15800a040402802f1d5b2b8ca5674504f4330310000000000046363070000000000000000 
000000000065450000b4fb6b400039 

$cat temp3 
3d3d1116cdcc57e58287d3f55285a1084b 

cevap

14
#!/usr/bin/perl 

undef $/; 
$_ = <>; 
$n = 0; 

for $match (split(/(?=3d3d)/)) { 
     open(O, '>temp' . ++$n); 
     print O $match; 
     close(O); 
} 
+0

sayesinde bu büyük çalışır ve tüm geçici dosyalar üzerinde çalışacak şekilde ben ayrıştırıcı kodu çalıştırmadan önce, ayrıştırıcı komut dosyası içinde bu komut arayabilir . –

+0

Öğrenme için hangi kitabı seçmeliyim? Perl. UNIX'te yeniyim ve son zamanlarda bash, sed ve awk öğrenmeye başladım. –

+3

Muhtemelen * [Öğrenme Perl] (http://www.amazon.com/dp/1449303587) *. –

-1

Duruma göre. Kendi dosyaya daha sonra

sed 's/\(.\)\(3d3d\)/\1#\2/g' FILE | awk -F "#" '{ for (i=1; i++; i<=NF) { print $i > "temp" i } }' 

ilk sed ekler bir alan/kayıt ayırıcı olarak #, awk# üzerine böler ve baskılar her "alanı": Ama tek bir satır ise varsayarak, sizinle gidebilir. Girdi dosyası zaten 3d3d bölünmüş ise

sonra gidebilirsiniz:

awk '/^3d3d/ { i++ } { print > "temp" i }' temp 

HTH

5

Bu işe yarayabilecek:

# sed 's/3d3d/\n&/2g' temp | split -dl1 - temp 
# ls 
temp temp00 temp01 temp02 
# cat temp00 
3d3d01f87347545002f1d5b2be4ee4d700010100018000cc57e5820000000000000000000000000087d3f513000000000000000000000000000000000001001001010f000000000026 58783100b354c52658783100b4 
# cat temp01 
3d3d0000ad6413400103231665f301010b9130194899f2ffffffffffff02007c00dc015800a040402802f1d5b2b8ca5674504f4330310000000000046363070000000000000000000000000065450000b4fb6b400039 
# cat temp02 
3d3d1116cdcc57e58287d3f55285a1084b 

DÜZENLEME:

Eğer orada Kaynak dosyadaki yeni satırlar, önce bunlarıkullanarak kaldırabilirsinizve daha sonra yukarıdaki sed komutunu kullanarak çıkın. Sonra bunları korumak isteyen ancak edin:

sed 's/3d3d/\n&/g;s/^\n\(3d3d\)/\1/' temp |csplit -zf temp - '/^3d3d/' {*} 

trick

16

yapmalıyım awk yılında RS değişken kaydederken ayırıcı tanımlamak için izin bunun için güzeldir. Böylece, her kaydı kendi temp dosyasında yakalamanız yeterlidir. En basit sürümü:

cat temp | 
    awk -v RS="3d3d" '{ print $0 > "temp" NR }' 

örnek metin göz alıcı 3d3d ile başlar, böylece ısı 1 boş bir dosya olacaktır. Ayrıca, göz alıcı kendisinin, geçici dosyalarının başlangıcında, söz konusu geçici dosyalar için gösterildiği gibi olmayacaktır. Son olarak, eğer çok fazla kayıt varsa, açık dosyalarda sistem limitine girebilirsiniz. Bazı küçük komplikasyonlar daha yakın istediğini getirmek ve daha güvenli hale getirecek:

cat temp | 
    awk -v RS="3d3d" 'NR > 1 { print RS $0 > "temp" (NR-1); close("temp" (NR-1)) }' 
+1

Khm, you don Bunun için kediye ihtiyacım yok. Ve eğer tek satırlı bir girişse, sadece ilk kaydı alacaksınız. Ve çıktı orijinal 'RS'yi de kaçıracak. 'echo' 3d3dsomething3d3danything '| awk 'BEGIN {RS = "3d3d"} {print}' 'sadece bir şey çıkartacaktır. –

+1

Ya da yanılmışım. Çözümünüzdeki tek sorun, çıktıdaki "RS" eksik. (Ve işe yaramaz kedinin kullanımı.) –

+2

@ZsoltBotykai RS, tartışıldığı gibi çıktıda. Ve kedi işe yaramaz: Veri üretimi ve işleme arasında mantıklı bir ayrım sağlar. Böylelikle “cat temp”, awk aşamasından önce hangi transformasyonların devam ettiği, ve awk ile zaten uzun çizgiye daha fazla eklemeden kaçınıyor. –

İlgili konular