파일의 모든 줄을 grep하고 패턴 일치 지점에서 파일로 줄을 씁니다.

파일의 모든 줄을 grep하고 패턴 일치 지점에서 파일로 줄을 씁니다.

예를 들어, temp.txt파일에는 다음 정보가 포함되어 있습니다.

adsf on line jhkjhvjdbvjvbvbdjkvn  
qerwtt on line fdgdgdgdd  
qwqertg on line safffasffaf  
wrt on line adaddsd

on line파일의 모든 줄을 grep하고 나머지 줄을 다른 파일에 쓰고 싶습니다 . 즉 temp.txt, 파일 처리 후 새 파일에는 다음이 포함되어야 합니다.

on line jhkjhvjdbvjvbvbdjkvn  
on line fdgdgdgdd  
on line safffasffaf  
on line adaddsd  

Linux 터미널에서 이 작업을 어떻게 수행할 수 있나요?

답변1

-o옵션을 사용 grep하여 필요한 부분만 선택하십시오. 귀하의 경우 패턴을 사용하여 줄의 시작 부분부터 줄 끝까지 on line .*부분을 선택하십시오 .on line

% grep -o 'on line .*' temp.txt >new.txt

% cat new.txt 
on line jhkjhvjdbvjvbvbdjkvn  
on line fdgdgdgdd  
on line safffasffaf  
on line adaddsd

답변2

vi이 질문의 태그와 자동 파일 편집을 찾았다는 사실을 고려하면POSIX 호환 ex명령sed이 사이트의 조언은 , 심지어 Perl 에 대한 방대한 양의 조언에 비해 미온적입니다. awk다음 은 필요한 필터링을 수행하는 POSIX 호환 명령입니다.grepex

ex -sc 'g/.*\(on line\)/s//\1/ | .w!>>output
q!' input

g명령에 새 줄이 포함되어 있음을 참고하세요 . 그러나 전역 명령을 종료하는 다른 명시적인 방법이 없기 때문에 이는 전체 POSIX 이식성에 필요합니다.최대구현에서는 여러 -c명령을 허용하며, 이 경우 다음 하나의 라이너가 동일하게 작동합니다.

ex -sc 'g/.*\(on line\)/s//\1/ | .w!>>output' -c 'q!' input

ex이 명령에는 정규식 마법과 -command 마법이 많이 있는데, ex잘 알려지지 않은 것 같으니 각 부분을 설명하겠습니다.

-s자동 모드에서 시작하여 ex"일괄 처리 준비"를 수행하므로 터미널에 아무 것도 출력되지 않습니다.

-c"파일을 열 때 다음 명령을 실행하십시오."를 의미합니다. ( input열려는 파일의 이름입니다.)

명령 ex자체는 실제로 두 가지 명령입니다.

g/.*\(on line\)/s//\1/ | .w!>>output
q!

g"전역" 명령으로, "지정된 정규식(나머지 줄)과 일치하는 파일의 모든 줄에서 다음 명령을 실행합니다"를 의미합니다.

주어진 정규식은 .*\(on line\)"0을 포함한 임의의 수의 문자 뒤에 "온라인"이 오는 것"을 의미하는 입니다. 괄호는 나중에 역참조를 위해 "온라인"을 캡처하는 데 사용됩니다.

실제로 g명령 자체는 이와 같을 수 있으며 g/on line/동일하게 작동합니다. 그러나 s내가 작성한 대체 명령은 다음을 사용합니다.아무것도 없다정규식의 경우 s//이는 "마지막으로 사용한 정규식 재사용"을 의미합니다. 그런 다음 명령 s을 사용하여 \1텍스트를 대체합니다. 이 경우에는 "온라인"을 의미합니다.

|명령의 파이프 기호는 ex쉘에서처럼 파이프를 나타내지 않습니다. 그와는 반대로,대개별도의 명령을 분리하는 데 사용되며 ex각 명령은 순차적이지만 독립적으로 실행됩니다. 그러나 g전역 명령은 예외입니다. 전역 명령 내에서는 수직 막대가 모든 명령을 구분합니다.이내에전역 명령 - 즉, 해당 명령만 실행합니다.정규식과 일치하는 줄에서전역 명령에 지정됩니다.

이 경우 수직선 뒤의 명령은 w의례적 명령이다. 이 주소 지정자가 없으면 "현재 줄"을 지정하는 점이 앞에 옵니다 .. 쓰기 명령은 쓰기를 수행합니다.모두파일, 현재 줄에 관계없이. (글로벌 명령에서 write 명령을 사용하므로 점을 생략하면 write 명령이일치하는 줄에는 바꾸기 명령이 실행됩니다! )

이는 >>"파일이 이미 존재하는 경우 오류를 발생시키는 대신 파일에 추가하십시오"를 의미합니다. 파일에 여러 번 쓰기 때문에 이는 필요합니다. 그렇지 않으면 다음과 같이 끝납니다.마지막출력 파일에 쓸 라인입니다. !위 의 >>의미는 "파일이아니요이미 존재하는 경우 오류를 발생시키는 대신 파일을 생성하고 해당 파일에 쓰십시오. ” (그렇지 않은 경우 !POSIX에서는 이러한 일이 발생할지 여부가 지정되지 않습니다.) 그리고 물론 output쓸 파일의 이름도 마찬가지입니다.

물론 마지막으로 q!"현재 파일에 대한 변경 사항을 저장하지 않고 종료"를 의미합니다. 파일의 여러 줄을 교체했지만 input이러한 변경 사항을 저장하고 싶지 않으므로 를 사용합니다 q!.


다음과 같은 다른 동등한 방법이 있습니다.

ex -sc '%s/.*\(on line\)/\1/e | v//d
w output | q!' input

그러나 이는 ePOSIX에서 사용할 수 없는 대체 명령에 대한 플래그를 사용합니다. (이 플래그를 생략하면 .*\(on line\)파일에서 정규식이 발견되지 않으면 일괄 처리가 중지됩니다.)


물론, 어디에서ex 진짜샤인이 들어있어요제자리에파일 편집. 그러나 위에 표시된 것처럼 한 파일을 다른 파일로 필터링하는 데 확실히 사용될 수 있습니다.

답변3

이 시도:

grep -o 'on line .*' temp.txt > out.txt

-o매개변수를 사용하면 grep이 원하는 행의 일치하는 부분만 출력하게 됩니다.

답변4

grep이 옵션을 지원하지 않는 경우 -o:

sed 's/^.*\(on line\)/\1/' temp.text > out.txt

또는 다음을 포함하는 줄을 원하는 경우 on line:

sed -n 's/^.*\(on line\)/\1/p' temp.text > out.txt

여러 번 발생하면 다음 on line으로 시작하는 줄의 일부가 인쇄됩니다.맨 오른쪽그런 일이 일어난다. 가장 왼쪽 항목의 경우:

sed '/on line/!d;s//\
&/;s/.*\n//' temp.text > out.txt

관련 정보