답변:
Sed 가 더 좋습니다.
그냥 해:
sed '/PATTERN/q' FILE
다음과 같이 작동합니다.
각 줄마다 다음과 일치하는지 확인합니다 /PATTERN
.
가장 효율적인 솔루션입니다.이 즉시 PATTERN
보이면 종료됩니다. 가 없으면 q
sed는 파일의 나머지 부분을 계속 읽고 아무 것도 수행하지 않습니다. 큰 파일의 경우 차이를 만들 수 있습니다.
이 트릭을 사용하여 에뮬레이션 할 수도 있습니다 head
.
sed 10q FILE
sed '/PATTERN/Q' FILE
일치하는 줄을 건너 뜁니다. Q
GNU 확장이므로 sed에서는 작동하지 않습니다.
sed
grep의 기능 대부분을 대체 할 수 있습니다.
sed -n '1,/<pattern>/ p' <file>
즉, 패턴이 일치 할 때까지 첫 번째 줄에서 인쇄합니다.
몇 가지 범위 예제
sed -n '/<pattern>/,$ p' <file> # from pattern to end of file
sed -n '/<pattern1>/,/<pattern2>/ p' <file> # from pattern1 to pattern2
일치하는 것을 포함하여 인쇄하십시오.
awk '{print} /pattern/ {exit}' filename
sed '/pattern/q' filename
일치 항목을 제외하고 최대 인쇄 :
awk '/pattern/ {exit} {print}' filename
sed '/pattern/Q' filename
Q
시원하지만 gnu 고유의 afaik sed -n '/pattern/!p;//q'
은 더 휴대하기 쉽습니다 .
!
합니다 p
라인에 적용 되지 일치 pattern
하지만, 다음은 //q
나 ... 혼란
//
"이전 정규 표현식"을 의미합니다 ( "빈 문자열과 일치"를 의미한다고 생각했습니다). 동일한 솔루션의 짧은 버전은 다음과 같습니다 sed -n '/pattern/q;p
.
다음과 같은 순수한 GNU grep
방법은 효율적이지 않습니다.
세 개의 s를 사용하여 파일 막대 에서 문자열 " foo " 의 첫 번째 인스턴스 까지 모든 것을 검색 하십시오 .grep
grep -m 1 -B $(grep -n -m 1 foo bar | grep -o '^[0-9]*') foo bar
" foo " 의 마지막 인스턴스와 일치 :
grep -oPz "(?s)[^\n]*${s}.*?\n.*?foo.*?\n" bar
참고 : 마지막에 대한 자세한 내용은 grep
:에서 찾을 수 있습니다 필요한 여러 줄 검색을위한 정규식 (GREP) .
sed
코드 자체 답변의 가치가 있거나 다른 코드 중 하나에 추가 될 수 있습니다. 7 다시 grep
S :이 있었으므로 아무 grep
대답은 ... (플러스, 대답은 할 수 없다 보여 왜 안.)
위의 Mikel의 답변에 추가 ...
모든 행을 인쇄하려면 포함 최대 아니지만 , 첫 번째 줄 FILE
포함을 PATTERN
시도 :
sed '/.*PATTERN.*/{s///;q;}' FILE
이것은 패턴을 포함하는 전체 행과 일치하고이를 빈 행으로 바꾸고 나머지 파일을 처리하지 않고 종료합니다.
추신:
마지막에 (다른 도구를 사용하지 않고) 추가 줄 바꿈이 인쇄되지 않도록 생각할 수있는 가장 쉽고 명확한 방법은 sed를 다시 실행하고 새 마지막 줄을 삭제하는 것입니다.
sed '/.*PATTERN.*/{s///;q;}' FILE | sed '$d'
... 어쨌든 우리는 이제 그 라인을 삭제하고 있기 때문에 이전 작업이 중복되어 다음과 같이 단순화 할 수 있습니다.
sed '/PATTERN/q' FILE | sed '$d'
sed
호출 로 수행하는 방법을 보여줍니다 .
tcsh
과 bash
별명, 나는 확인에 필요한 I 표준과 GNU 모두에서 작동하는 비교적 간결한 한 줄 솔루션을 가지고있었습니다 sed
(이동성을 위해). 귀하의 기여가 매우 잘 충족 될 수있는 모든 요구 사항. sed
매우 드물게 사용하는 사람으로서 , 가장 중요한 요구 사항은 몇 년 전부터 쉽게 편집하거나 용도를 바꾸고 싶을 때 빠르게 이해할 수있는 것이 었습니다.
일상 업무에서 기본 도구 만 기억하고 덜 우아하고 덜 효율적인 솔루션을 기꺼이 받아들이려는 사람들에게 :
head -n $(grep -n pattern filename | cut -d: -f1) filename
이 명령이 스크립트를위한 것이라면 더 우아하고 (아마도 효율적인) 솔루션을 찾을 것입니다. 이것이 일회성 명령이거나 스크립트를 버리면 상관 없습니다.
다음 중 하나를 사용할 수도 있습니다.
tac ./test | grep -B $(cat ./test | wc -l) -m 1 'pattern'|tac
또는
tac ./test |head -n $(tac ./test | grep -n 'pattern' | cut -d: -f1 | head -n 1)|tac
또는
tac ./test |sed ':a;N;$!ba;s/\n/'"pattern"'/g' | sed 's/'"patternpattern"'/\n/g'|head -n 1|sed 's/'"pattern"'/\n/g'|tac
첫 번째 옵션은 OP가 제안한 것과 매우 유사하며 파일에서 줄을 계산하여 컨텍스트 전에 충분한 줄을 표시하도록합니다.
두 번째 옵션은 첫 번째 일치 행 번호를 검색하고 (내부 'head'를 변경하여 변경할 수도 있음) 해당 번호에서 head를 사용합니다
마지막 옵션은 모든 새 줄을 일치 항목으로 바꾸고 두 개의 인접한 일치 항목을 새 줄로 바꿉니다. 이 결과는 두 개의 일치 항목 사이의 모든 텍스트 블록에 대한 줄입니다. 그런 다음 'head'를 사용하여 첫 번째 줄 (텍스트 블록을 첫 번째로 일치시킬 때까지 일치)을 선택하고 각 일치 항목을 새 줄로 다시 변환합니다. 이 옵션은 파일이 다음 형식 인 경우에만 작동합니다
pattern
texttexttext
texttexttext texttexttext
texttexttexttexttexttexttexttexttext
pattern
texttexttext
pattern
texttexttext
texttexttexttexttexttexttexttexttext
기타 등등
sed
하단에있는 명령이 엉뚱 하기 때문에 어떻게 작동하는지 설명해보십시오 .