첫 줄이 특정 패턴과 일치하는 경우에만 파일 내용을 인쇄하는 방법은 무엇입니까?


11

스크립트를 작성 중입니다. 파일의 첫 번째 줄이 특정 패턴과 일치하는지 확인한 다음 파일을 인쇄하는지 확인하고 싶습니다. 어떻게하면 되나요?

패턴을 확인하려면 어떻게합니까? 패턴을 확인하고 출력을 기반으로 무언가를 수행하는 방법이 있습니까?

편집 :이 질문을보십시오 : https : //.com/questions/5536018/how-to-get-match-regex-pattern-using-awk-from-file

나는 이와 같은 것을 원하지만 그들 중 누구도 나를 위해 일하지 않았다. 기본적으로 첫 번째 줄이 정규식 패턴과 일치하는지 여부를 확인하고 그 줄에 따라 파일 줄을 인쇄하고 싶습니다.


1
당신이 기대하는 결과는 무엇입니까? 찾고있는 패턴이 무엇입니까? 지금까지 뭐 해봤 어?
tachomi

@tachomi 님이 수정했습니다
Mathew

답변:


17

당신은 그것을 할 수 있습니다 ed:

ed -s infile <<\IN 2>/dev/null
1s/PATTERN/&/
,p
q
IN

여기서 비결은 온라인으로 교체 PATTERN하는 1st것입니다. ed지정된 패턴을 찾지 못하면 오류가 발생하므로 ,p(전체 파일 인쇄) 1s/PATTERN/&/성공한 경우에만 실행됩니다 .

또는과 sed:

sed -n '1{
/PATTERN/!q
}
p' infile

q첫 번째 줄이 없습니다 (않는 경우 UITS !) 일치를 PATTERN, 그렇지 않으면 p모든 행을 rints.
또는 Toby Speight가 지적한 것처럼 GNU는 sed다음 과 같습니다.

sed '1{/PATTERN/!Q}' infile

Qq패턴 공간 과 동일 하지만 패턴 공간을 인쇄하지 않습니다.


당신은 할 수 Q대신 qGNU가 나오지 위해, 또는 dq(휴대용) 그래서으로 필요하지 않기 -n플래그와 p명령을 : sed '1{/PATTERN/!Q}' infile또는 sed -e '1{' -e '/PATTERN/!{' -e 'd' -e 'q' -e '}' -e '}' infile각각.
Toby Speight

d항상 나를 잡아주는 명령주기를 다시 시작합니다 ! :-|
Toby Speight

GNU sed에서 첫 번째 sed명령은 sed: -e expression #1, char 10: extra characters after command(때문에 p) 불평 하지만 ed마지막 sed제안은 잘 작동합니다.
Skippy le Grand Gourou

NB :이 답변에서 제공하는 솔루션은 다른 답변보다 파이프에 적용 할 수 있다는 장점이 있습니다.
Skippy le Grand Gourou

1
@SkippyleGrandGourou-세미콜론으로 명령을 분리하지 않고 하나의 라이너로 바꾸려고 시도했습니다-이것이 올바른 방법입니다sed -n '1{/PATTERN/!q};p'
don_crissti

15

POSIX 도구 상자 :

{ head -n 1 | grep pattern && cat; } <file

1
{double} <달콤하다.
mikeserv

@ mikeserv : 새로운 사람이 혼란을 피하기 위해 사용하려고하지만 Stephane 편집이 더 명확합니다.
cuonglm

8
 awk '/pattern/{print FILENAME}; {nextfile}' ./*.txt

txt현재 디렉토리에서 숨겨지지 않은 파일 의 이름을 첫 번째 행이 확장 정규식 pattern지원 되는 awk보충nextfile 과 일치하는 파일을 인쇄합니다 .

파일 이름을 인쇄하는 대신 전체 파일 내용을 인쇄하려면 다음을 수행하십시오.

 awk 'FNR == 1 && ! /pattern/ {nextfile}; {print}' ./*.txt

그것은 하나의 명령 만 실행한다는 점에서 효율적이지만 awk큰 파일로 파일의 내용을 덤프하는 가장 효율적인 명령은 아니지만 다음과 같은 작업을 수행하여 더 나은 성능을 얻을 수 있습니다.

 awk '/pattern/{printf "%s\0", FILENAME}; {nextfile}' ./*.txt |
   xargs -r0 cat

즉, awk일치하는 (0 구분) 파일 목록을 인쇄하고 cat해당 내용을 덤프 하는 데 에만 사용 하십시오 .


6

쉘 스크립트를 작성하는 경우 다음과 같이 할 수 있습니다.

for file in ./*; do head -n 1 "$file" | grep -q 'PATTERN' && cat "$file"; done

또는 Perl에서 :

perl -Tlne '$f = /PATTERN/ if $. == 1; print if $f; $. = 0 if eof' ./*

@ Stéphane Chazelas :에 close ARGV할당하는 것보다 더 많은 관용구 $.입니다.
cuonglm

@terdon Yours는 한 줄에 코드 골프처럼 보이며 변수 이름 주위에 괄호가 없으며 깨끗한 구조를 장려하지 않습니다. 내가 게시했을 때 달러 기호가 빠졌습니다. 그것은 bash를 가르치는 방법이 아닙니다. 나는 그 요소들이 당신이 가지고있는 펄 배경에서 온다고 가정하므로, 당신은 용서받을 것입니다! ;)

@guest 안녕하고 사이트에 오신 것을 환영합니다! 답변이 실제 질문에 답변하는 경우에만 답변을 게시해야하므로 답변을 의견으로 변환했습니다. 이것은 고전적인 의미의 포럼이 아니며 여기서 순수한 Q & A 만 원합니다. 도움말 센터를 보거나 사이트를 더 잘 이해하기 위해 둘러보기 를 원할 수 있습니다 . 즉, 내 배경은 실제로 생물학에 있으므로 그렇습니다. 코드는 깨끗하지 않습니다. 괄호가 무엇을 막을 수 있습니까?
terdon

@guest 아, 죄송합니다. 댓글을 달 수 없습니다. 채팅 으로 와서 설명 해주십시오. 무언가를 배울 수있을 것입니다.
terdon

5

Oldschool, 문장을 표준 명령으로 번역하십시오.

for file in *; do
    if head -n 1 "${file}" | grep -q 'PATTERN'; then
        cat "${file}"
    fi
done

배쉬를 배우는 것은 좋은 시작입니다. 빠른 솔루션이 필요한 경우 sed-, awk- 또는 perl-answers를 시도하십시오. 둘 다 좋지만 학습에 필요한 언어 일 것입니다.

아주 간단한 예제이므로 더 배우고 싶다면 루비, PHP, js (예 : nodejs) 또는 파일 액세스를 허용하는 다른 언어에서도 동일하게 시도 할 수 있습니다. C / C ++ 또는 Java조차도 작은 작업으로 쉽게 관리 할 수 ​​있어야합니다.


1
이것은 기본적으로 대신 사용 하는 것을 제외하고는 것과 동일 합니다. if/else[ ] &&
terdon
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.