2011-11-09 6 views
16

나는 hexdump와 몇 가지 awk 및 sed 명령을 사용하여 일반 파일로 변환하는 이진 파일을 가지고 있습니다. 출력 파일은 다음과 유사합니다 -한 파일을 패턴을 기반으로 여러 파일로 분할

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

임시 파일에는 자주 반복되는 안구 포수 (3d3d)가 있습니다. 그들은 일종의 새로운 바이너리 레코드의 시작을 나타냅니다. 그 아이 캐쳐를 기반으로 파일을 분할해야합니다.

내 원하는 출력은 임시 파일에있는 아이 캐처 수를 기준으로 여러 개의 파일을 갖는 것입니다.

그래서 내 출력은 다음과 같이 보일 것 - 그것은 당신의 temp 파일이나하지에 한 줄의 경우

$cat temp1 
3d3d01f87347545002f1d5b2be4ee4d700010100018000cc57e582000000000000000 
0000000000087d3f513000000000000000000000000000000000001001001010f00000000 
002658783100b354c52658783100b4 

$cat temp2 
3d3d0000ad6413400103231665f301010b9130194899f2ffffffffffff02007c00dc0 
15800a040402802f1d5b2b8ca5674504f4330310000000000046363070000000000000000 
000000000065450000b4fb6b400039 

$cat temp3 
3d3d1116cdcc57e58287d3f55285a1084b 

답변

14
#!/usr/bin/perl 

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

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

덕분이 잘 작동하고 모든 임시 파일에 실행되도록 내가 파서 코드를 실행하기 전에 내 파서 스크립트에서이 스크립트를 호출 할 수 있습니다 . –

+0

Perl을 배우기 위해 어떤 책을 골라야하는지에 대한 제안. 나는 UNIX에 익숙하지 않고 최근 bash, sed 및 awk를 배우기 시작했습니다. –

+3

아마 * [Learning Perl] (http://www.amazon.com/dp/1449303587) *. –

-1

상황에 따라 다르다. 자체 파일에 다음

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

첫 번째 sed 삽입 필드/레코드 분리로 #, awk#에 분할 및 인쇄마다 "필드":하지만 한 줄의 경우 가정, 당신은 갈 수 있습니다. 입력 파일이 이미 3d3d에 분할되어있는 경우

다음에 갈 수 있습니다 :

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

HTH

5

이 작동 할 수 있습니다 :

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

편집 :

하는 경우가 소스 파일의 개행은 먼저을 사용하여 제거 할 수 있습니다.을 입력 한 다음 위의 sed 명령을 통해 출력을 파이프하십시오. 당신이 다음을 보존하고자하지만 경우

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

트릭

16

을해야 awkRS 변수는 레코드 분리를 정의 할 수 있도록 이에 대한 좋은 것입니다. 따라서 각 레코드를 자체 임시 파일로 캡처하면됩니다. 가장 간단한 버전은 다음과 같습니다

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

샘플 텍스트는 눈 포수 3d3d로 시작, 그래서 TEMP1은 빈 파일이 될 것입니다. 또한, 눈 - 포수 자체가 임시 파일의 시작 부분에되지 않습니다, 질문에 임시 파일에 대한 표시되었습니다. 마지막으로, 많은 레코드가있는 경우 열린 파일에 대한 시스템 제한을 실행할 수 있습니다. 약간의 합병증은 가까이 당신이 원하는 무엇을 가져하고 안전 할 것입니다 :

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

Khm, 너 don 그것을 위해 고양이가 필요 없습니다. 단 한 줄짜리 입력이라도 첫 번째 레코드 만 가져옵니다. 그리고 출력물은 원래의 'RS'도 놓칠 것입니다. 'echo '3d3dsomething3d3danything'| awk 'BEGIN {RS = "3d3d"} {print}''는'무언가'만을 출력합니다. –

+1

아니면 틀 렸습니다. 솔루션의 유일한 문제점은 출력에 'RS'가 없습니다. (쓸데없는'고양이 '사용). –

+2

@ZsoltBotykai RS는 논의 된대로 출력됩니다. 고양이는 쓸모가 없습니다. 데이터 생성과 처리 사이를 논리적으로 분리시킵니다. 따라서 'cat temp'는 awk 단계 이전에 어떤 변환이 진행되던간에 awk로 이미 긴 행을 추가하는 것을 피하면서 기다립니다. –

관련 문제