2016-06-03 3 views
1

파일의 여러 줄이 bash에 있는지 확인하고 싶습니다. 예를 들어, 나는 다양한 조합으로 여러 가지 시도bash에서 grep로 && 사용하는 방법

if grep -q string1 "/path/to/file";then 
    echo 'exists' 
else 
    echo 'does not exist' 
fi 

: 나는 단지 한 줄 작동 grep -q 사용하는 이처럼

if grep -q [ string1 ] && grep -q [ string2 ] "path/to/file";then

나는 또한 -E와 그것을 시도 :

grep -E 'pattern1' filename | grep -E 'pattern2'

하지만 아무 것도 작동하지 않는 것 같습니다. 어떤 아이디어?

if grep -q 'string1' /path/to/file; then 
    if grep -q 'string2' /path/to/file; then 
     echo exists 
    else 
     echo 'does not exist' 
else 
    echo 'does not exist' 
fi 

을 또는 :

+2

'grep -q string_1 파일 && grep -q string_2 file'? – iruvar

+0

@iruvar 답변을 게시하십시오 – Barmar

+0

이 시도했지만뿐만 아니라 스크립트가 끝나지 않습니다 – Tom

답변

1

를 사용하여 검색하는 "-q"를 사용할 수 있습니다를 내가 여기에 넣으십시오 :

grep -q string_1 file && grep -q string_2 file 

지금 내 공헌입니다[email protected] anubhava의 계산 상 더 복잡한 awk 대답은 파일을 한 번만 읽습니다. @ iruvar의 간단한 대답은 파일을 세 번 읽습니다.

awk   11.730 s 
grep && grep 0.258 s 

no.

이것은 분명히 파일 시스템 대 CPU의 속도와 캐싱이 얼마나 많은지에 달려 있지만 아마도 시스템의 일반적인 B +/A- 워크 스테이션 인 grep kw1 file && grep kw2 file && grep kw3 file은 @ anubhava의 awk 솔루션입니다. 이것은 ssd와 스핀들 급습 모두에 해당됩니다. (자세한 사항 : 테스트 파일은 160M 5,000,000 라인, 그리고 5 백만에, 첫 번째 줄에 2.5 백만에 kw2kw3kw1했다.) 당신이 해결할 수있는 경우

일부 쉽게 최적화, 예를 들어, 수 전체 줄을 일치시켜 문제를 해결하려면 (grep -x); 이 경우에는 두 배 빠릅니다. 같은 테스트 파일을

for f in *.txt; do 
    grep -q kw1 $f && grep -q kw2 $f && grep -q kw3 $f 
done 

grep -l | xargs grep : 루프에 반대

grep -l kw1 *.txt | xargs grep -l kw2 | xargs grep -q kw3 

: (예,> 1,000) 파일이 grep -lxargs를 사용하는 빠른 많은

grep && grep처럼 0.258 초가 걸렸습니다. 두 개의 테스트 파일을 사용하면 여전히 grep && grep보다 빠릅니다. 2000 줄의 각각 5,000 줄의 테스트 파일이 있었고 어떤 것도 일치하지 않았고 grep -l | xargs grepgrep && grep보다 10 배 빠릅니다.

1

이 같은 그것을 할 수

실행하는 여러가 grep 당신이 파일에 여러 문자열의 존재를 주장하는이 gnu-awk 명령을 사용하여 명령보다는
grep -q 'string1' /path/to/file && 
grep -q 'string2' /path/to/file && 
echo exists || 
echo 'does not exist' 
+0

나는 그가 성공하기 위해 파일 내에 존재하는 모든 패턴을 필요로한다고 생각한다. – iruvar

+0

이것은 OR이 아니라 AND이다. – Barmar

+0

@Barmar : edited ... – Jahid

3

:

awk -v RS='\\Z' '/string1/ && /string2/ && /string3/{e=1} END{exit !e}' file && 
echo 'exists' || echo 'does not exist' 
  • RS=\Z
  • exists을 인쇄 할 AWK하는 모든 검색 단어가 입력 파일에 존재 있는지 확인합니다 여러 검색어 사이 &&를 사용하여 하나의 레코드 분리
  • 의 모든 입력을 읽 만 3 검색어가 존재하는 경우 입력 파일.
+0

단일 레코드 일을 수행하는 데 메모리가 비효율적 인 것으로 보인다. 여기에 그 원인이 있습니까? ("여러 줄 [...] 존재"를 통해 개별 패턴이 개별 줄과 일치 함을 지정하는 질문을 읽었습니다.) –

+0

우리는 다른 라인에서 패턴을 찾으려고합니다.나는 벤치마킹을하지 않았지만 IMO는'grep -q string1 file && grep -q string2 file && grep -q string3 file'보다 더 효율적일 것입니다. – anubhava

+0

나는 이것이 다중 greps보다 IO-IO 효율이 높다는 것에 확실히 동의합니다. 왜 awk 코드가 패턴을 라인 단위로 적용하는지, 어떤 패턴이 매치 할 때마다 플래그를 설정하지 않고 (아마도 두 가지가 모두 조만간 종료 될 때) awk 코드가 작동하지 않을 때 메모리 요구 사항을 완화해야하는 이유를 알지 못한다. 큰 입력. –

1

질문에 몇 가지 모호한 점이 있지만, pattern_1과 pattern_2가 같은 줄에없는 파일에 존재한다고 가정하면이 작업을 수행 할 수 있습니다.

for file in *; do 
    egrep -q pattern_1 $file && egrep -q pattern_2 $file && echo $file 
done 
+2

더 많은 인용문이 필요합니다. '$ file'이 아닌''$ file ''이거나 공백이있는 파일 이름으로 인해 실패하게됩니다. –

+2

'touch '* .txt''로 만든 파일을 가지고 있다면 그것도 기이하게 행동 할 것입니다 - 모든 텍스트 파일을 grep하고 모든 텍스트 파일을 나열합니다. 쪽으로. 따옴표는 당신의 친구입니다. –

1

grep -p하면 같은 줄에 다중 패턴과 일치 할 수

grep -P '(?=.*string1)(?=.*string2)' file 

string1string2 일치하는 라인을 인쇄합니다.

(?=...)positive lookaheads이며 패턴 일치와 일치하지 않습니다.

그리고 -z는 전체 파일을 후루룩 소리 내며 먹기됩니다 @iruvar이 답변으로 자신의 의견을 게시하지 않았기 때문에,

% seq 1 100 | grep -qzP '(?=.*1)(?=.*5)'; echo $? 
0 
% seq 1 100 | grep -qzP '(?=.*1)(?=.*a)'; echo $? 
1 
+0

'grep -e 'pattern1'-e 'pattern2''를 사용할 수있을 것 같아요. –

+0

@ BenjaminW. 논리적 인 OR을하지 않겠습니까? 나는 OP가 논리적 인 것을 원한다고 생각합니다 – andlrc

+0

아, 네 말이 맞아서 그가 원하는 것처럼 보입니다. 내 잘못이야. –

0

당신이 그렙

if grep -q string1 "/path/to/file" && grep -q string2 "/path/to/file";then 
     echo 'exists' 
    else 
     echo 'does not exist' 
    fi 
+0

그건 OR입니다. 질문은 AND를 요구합니다 (서로 다른 행에 일치하는 패턴이 예상 됨). –

+0

'||'은 여전히 ​​OR 인 반면, 당신이'&& '가되도록 수정하면 Jahid가 답을 앞에 둡니다. –

+0

내 실수 \t 지금 업데이트하십시오. "&&" –

관련 문제