예를 들어, 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 호환 명령입니다.grep
ex
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
그러나 이는 e
POSIX에서 사용할 수 없는 대체 명령에 대한 플래그를 사용합니다. (이 플래그를 생략하면 .*\(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