2014-07-09 4 views
2

파일에 저장하는 항목과 일치 할 때마다 여러 번있는 파일에서 X에서 Y까지를 가져와야합니다.pipe sed 명령을 사용하여 여러 파일 만들기

\x00START how are you? END\x00 
\x00START good thanks END\x00 
sometimes random things\x00\x00 inbetween it (ignore this text) 
\x00START thats nice END\x00 

이제 각 파일 (/folder/demo1.txt, /folder/demo2.txt 등) 명령을 실행 한 후이 있어야한다 : 여기

은 예제 파일 (demo.txt)입니다 'START'이외에 \ x00START와 END \ x00 사이의 내용 (\ x00은 null 임) 'END'가 아닙니다.

/folder/demo1.txt에 "START how are you?"라고 표시되어야합니다. /folder/demo2.txt는 "START good thanks"라고 말해야합니다.

기본적으로 "어떻게 지내십니까?" 'echo'를 사용하면 'START'를 앞에 붙일 수 있습니다.

매우 큰 바이너리 파일을 다루고 있습니다.

나는 현재

sed -n -e '/\x00START/,/END\x00/ p' demo.txt > demo1.txt 

를 사용하고 있지만, 예상대로 (그것이 '\ x00START'전 라인을지고있어 첫 번째 '최종 \의 x00에서'에서 멈추지 않는다) 작동하지 않습니다.

+0

참고로, 나는'sed'가 일반적으로 바이너리 파일과 잘 어울리는 것을 생각하지 않는다. – merlin2011

+0

아, 어떤 아이디어라도 내가 사용할 수 있을까요? 나는 grep을 시도했지만 바이너리 파일에서도 잘 동작하지 않았다. – user3786834

+0

어떤 종류의 파일입니까? 왜 그 안에 null 문자가 있습니까? 어쨌든, 바이너리 모드에서는'-b' 옵션을 사용하고 (* nix에서는 상관 없습니다),'\ x00'을 사용하여 널 문자를 찾습니다. – ooga

답변

2

글로벌 m에 대한 g, 시도 :

awk -v RS='\0START|END\0' ' 
     length($0) {printf "START%s\n", $0 > ("folder/demo"++i".txt")} 
     ' demo.txt 
  • RS='\0START|END\0'[입력으로 동작하는 정규 표현식을 정의 ] 레코드 분리 자은 입력 파일을 012 사이의 문자열 (바이트 시퀀스)로 레코드로 나눕니다.및 END\0 (\0NUL (null char.) 여기를 나타냄).
    • 다중 문자를 사용하는 regex 기반 레코드는 POSIX와 호환되지 않습니다. GNUawk은 (mawk일반적으로는이지만 겉으로보기에는 NUL chars가 아닙니다.).
  • length($0) 패턴이 기록 비어 있지 않은 경우 연관된 동작 ({...} 참조)은 실행되는 것을 보장한다.
  • {printf "START%s\n", $0 > ("folder/demo"++i)}"START"이 앞에 오는 각 비어 있지 않은 레코드를 folder/demo{n}.txt" 파일로 출력합니다. 여기서 {n}1으로 시작하는 시퀀스 번호를 나타냅니다. grep 그 자체로 깨끗한 라인에 원하는 텍스트를 찾을 수 있도록
+0

+1로 여러 줄 문제를 해결했습니다. 깔끔한 접근법입니다. 사용하는 것을 기억해야합니다. – Tiago

+0

고마워요, @ 티아고; multi-char., regex-based 'RS' 값은 일반적으로 _both_ GNU'awk'와'mawk'에서 작동합니다.이 특별한 경우에'mawk'는 작동하지 않습니다. 아마도'NUL' 문자 때문일 것입니다. – mklement0

+0

지금 시도하고 다시 연락 드리겠습니다. – user3786834

1

당신은 그것에 대해 grep를 사용할 수 있습니다

grep -Po "START\s+\K.*?(?=END)" file 
how are you? 
good thanks 
thats nice 

설명 :

  1. -P

    는 펄 정규식
  2. -o 추출 할 수 있도록
  3. -K 긍정적는
  4. 을 lookbehind에만 일치하는 패턴긍정적 예측

편집 :START\00 일치하고 END 사이에 나타날 수 있습니다

echo -e '\00START hi how are you END\00' | grep -aPo '\00START\K.*?(?=END\00)' 
hi how are you 

EDIT2 : 멀티 라인 만 한 줄을 일치합니다 그렙를 사용하는 솔루션을, 대신 perl을 사용하는 것이 좋습니다. 문법은 매우 유사합니다

새로운 여기에 무엇
echo -e '\00START hi \n how\n are\n you END\00' | perl -ne 'BEGIN{undef $/ } /\A.*?\00START\K((.|\n)*?)(?=END)/gm; print $1' 
hi 
how 
are 
you 

:

  1. undef $/ 정의를 해제 INPUT
  2. (.|\n)* 점은 거의 모든 문자와 일치하지만, 그렇지 않은 '\ n을'기본값 분리 $/ 일치하는 \n 그래서 여기에 추가해야합니다.당신이 GNUawk 경우
  3. /gm 수정, 멀티 라인
+0

도움을 주셔서 감사합니다.하지만 'START'와 'END'가 내용의 중간에 나타날 수 있으므로 16 진수도 사용해야합니다. – user3786834

+0

@ user3786834 내 답변을 편집했습니다. 바이너리의 경우 '-a' 스위치를 텍스트로 사용하십시오. – Tiago

+0

Snazzy, 작동 중입니다! Tiago 감사합니다. 참고 : 16 진수를 사용하려면 grep을 얻으려면 \ 00이 아니라 \ 00입니다. – user3786834

0

나는 줄 바꿈에 널 (null)을 번역하는 것입니다 : 거기에서

tr '\000' '\n' < yourfile.bin | grep "^START" 

당신이 이전 sed로 걸릴 수 있습니다.

관련 문제