2014-11-06 1 views
0

나는이 수업에서 나를 도울 수 있기를 바라고있는 수업에 grep 사용법을 익히는 데 어려움을 겪고 있습니다. 과제는 다음과 같습니다.사전의 Grep 필터링

grep을 사용하여 리눅스 사전에서 한 글자를 한 번 복제 한 5 글자 소문자 단어를 모두 인쇄하십시오 (a 및 b는 두 단어에 두 번 있기 때문에 유효하지 않습니다). 이 인쇄물 옆에 복사 된 문자 다음에 알파벳순으로 오름차순으로 중복되지 않은 문자를 사야합니다.

Teacher는 최종 단어 집합을 다시 포맷하기 위해 몇 가지 (6 개의) grep 문 (결과를 다음 grep으로 파이핑)과 sed 문 (문자열 편집기)을 사용해야 할 필요가 있다고 지적하면서이를 읽기 루프에서 3 개의 비 연속 문자를 떼어 내서 정렬하십시오.

Sample Output: 
aback a bck 
abaft a bft 
abase a bes 
abash a bhs 
abask a bks 
abate a bet

나는 더 많은 5 개 글자 단어,

grep "^.....$" /usr/share/dict/words |
+0

아마도 당신과 http://stackoverflow.com/questions/26789662/bash-script-pipes-not-working가해야 이것에 함께 일하십시오. =) 허용한다고 가정합니다. –

답변

0

첫 번째 비트는 분명,이 단어 만에 내려받을 grep를 사용하는 인쇄 한 후 수행하는 방법을 알아 냈하지 않은 에있는 하나의 중복. 나는 당신에게 그것을하는 방법에 대한 단서를 줄 것이다.

키는 역 참조을 사용하여 이전 표현식과 일치하는 항목이 다시 표시되도록 지정할 수 있습니다. 당신이

grep -E "^(.)...\1...\1$" 

를 작성하는 경우 그럼 당신은 다섯 번째와 아홉 번째 위치에 다시 나타나지 시작 문자가 모든 단어를 얻을 수 있습니다. 괄호의 요점은 나중에 괄호 안에있는 것과 일치하는 것을 참조 할 수 있도록하는 것입니다. \1 (첫 번째 괄호 묶음에 일치시키기 위해)을 사용하면됩니다.

단어가 어느 곳에서나 복제되어야한다고 말하고 싶지만 다소 복잡하지만별로는 아닙니다. 문자를 대괄호로 묶은 다음 임의의 문자 수를 입력 한 다음 반복 문자 (^ 또는 $이 지정되지 않은 문자)를 원합니다.

두 개 이상의 중복 된 부분도 포함되므로 다음 단계에서는이를 필터링하는 것입니다. grep -v 호출을 통해이를 수행 할 수 있습니다. 적어도 하나의 중복 문자가있는 5 자 단어 목록을 얻은 후에는 grep -v 전화를 통해 두 개의 (또는 그 이상) 중복을 제거한 전화를 보내십시오. (.) 및 또 다른 (.)을 갖습니다. \1\2이며 여러 주문에 표시 될 수 있습니다.

(.)\1 및 또 다른 \1이있는 항목을 제거해야합니다. 그 이유는 3 번 발생하는 문자가 있기 때문입니다.

아무래도 시작하기에 충분해야합니다.

+0

예 다른 사용자가 여기에서 작업하는 프로젝트와 동일한 프로젝트입니다. http://stackoverflow.com/questions/26789662/bash-script-pipes-not-working. 이것을 해결책으로 표시하겠습니다. – Dalitive

0

다음 단계는 중복 문자가 포함 된 5 글자 단어를 찾는 것입니다. 그렇게하려면 역 참조를 사용해야합니다. 예 :

grep "[a-z]*\([a-z]\)[a-z]*\$1[a-z]*"

$1 픽업 첫 번째 괄호 그룹의 내용을 다시 해당 그룹과 일치 할 예정이다. 이 경우 하나의 문자와 일치합니다.이 기능에 대한 자세한 내용은 http://www.thegeekstuff.com/2011/01/advanced-regular-expressions-in-grep-command-with-10-examples--part-ii/을 참조하십시오.

다음으로 문자가 3 번 반복되거나 2 개의 문자가 반복되는 경우를 걸러 내야합니다. 동일한 종류의 역 참조 트릭을 사용해야하지만 grep -v을 사용하여 결과를 필터링 할 수 있습니다.

sed를 사용하여 최종 표시 할 수 있습니다. Grep은 올바른 라인을 구성 할 수 있도록 허용합니다.

+0

현재이 제품을 가지고 있으며 출력이 없습니다.

grep "^.....$" /usr/share/dict/words | grep "[a-z][a-z][a-z][a-z][a-z]" | grep "[a-z]*\([a-z]\)[a-z]*\$1[a-z]*" 
Dalitive

+0

이 답변에는 많은 문제가 있습니다. 링크가 죽었습니다. 역 참조는'$'를 사용하지 않습니다. 그리고 처음과 끝에서'[a-z] * '는 필요 없습니다. 그리고'-E'를 사용하면 구문이 단순 해집니다. –

0

사전에는 대문자와 문자가 아닌 문자 및 남유럽에서 사용 된 이상한 문자가 포함됩니다. "è"라고 말하십시오.

"A"와 "a"를 구별하려면 "A"와 "a"가 같은 문자 인 경우 자동으로 수행되며 ALL grep 호출시 -i 옵션을 사용해야 만 grep은 대소 문자를 무시합니다.

다음으로, 당신은 항상 소위 backslashitis 당신이 grep에 전달하려는 정규 표현식에를 근무력증 방지하기 위해 -E 옵션을 전달하려는.

은 출력에서 ​​정규 표현식과 일치하는 행을 제외하고 올바른 옵션은 -v입니다. 단일 grep 호출에 여러 가지 정규 표현식에를 지정하려면

결국,이 방법 (BTW 단지 예)

예선은 우리를있는
grep -E -i -v -e 'regexp_1' -e 'regexp_2' ... -e 'regexp_n' 

, 대답을 사용,의 앞으로 살펴 보자입니다 chiastic-security에서 procedings을 이해하는 기준으로

  1. 가 단지 이러한 가능성 5 문자열에 중복을 찾을 수 있습니다

    ,
    (.)\1 
    (.).\1 
    (.)..\1 
    (.)...\1 
    

    grep -E -i -e 'regexp_1' ...

  2. 지금 당신은 모든 복식을 가지고 있지만, 이것은 다음과 같은 패턴으로 식별하는 등 트리플을 배제하지 않는다

    (.)\1\1 
    (.).\1\1 
    (.)\1.\1 
    (.)..\1\1 
    (.).\1.\1 
    (.)\1\1\1 
    (.).\1\1\1 
    (.)\1\1\1\1\ 
    
    (편집 추가 일치의 cople이 패턴을 세 배로 추가) 당신이이 패턴을 제외 할

    , 그 시점에서 너무 grep -E -i -v -e 'regexp_1' ...

  3. , 당신은 단어의 목록을 가지고 당신이 더블 더블을 삭제하려면 적어도 같은 문자의 몇없이 트리플 등,이 더블 더블

    (.)(.)\1\2 
    (.)(.)\2\1 
    (.).(.)\1\2 
    (.).(.)\2\1 
    (.)(.).\1\2 
    (.)(.).\2\1 
    (.)(.)\1.\2 
    (.)(.)\2.\1 
    

    일치하는 정규 표현식에 있으며 이 패턴 라인을 제외하려면 당신이 원하는 그 grep -E -i -v ...

마지막 힌트 있도록 압도하는 피하고, 당신이 정말 당신이 무슨 일을하는지 이해할 수 있도록, 당신의 작업 디렉토리에 head -n 3000 /usr/share/dict/words | tail -n 300 > ./300words을 사전의 몇 백 개 라인을 복사 내 대답과 함께 재생 출력의 부피만큼.

예, 이것은 완전한 대답은 아니지만 너무 많을 수 있습니다. 그렇지 않습니까?

+0

두 번째 및 세 번째 grep 실행은 병합 될 수 있습니다. 둘 다'-v' 옵션을 사용하여 실행되기 때문입니다. – gboffi

1

는 철저하게 확인하지 못했지만,이

tr '[:upper:]' '[:lower:]' | egrep -x '[a-z]{5}' | sed -r 's/^(.*)(.)(.*)\2(.*)$/\2 \1\3\4/' | grep " " | egrep -v "(.).*\1" 

일을하지만 누군가가 여기에 그것을 볼 수 있기 때문에 방법을 할 수 있습니다.

+0

정말 좋은데, 특히 내 짐승의 노력과 비교하면 ... – gboffi

1

모든 하나는

sed -n ' 
# filter 5 letter word 
/[a-zA-Z]\{5\}/ { 

# lower letters 
     y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxya/ 

# filter non single double letter 
     /\(.\).*\1/ !b 
     /\(.\).*\(.\).*\1.*\1/ b 
     /\(.\).*\(.\).*\1.*\2/ b 
     /\(.\).*\(.\).*\2.*\1/ b 

# extract peer and single 
     s/\(.\)*\(.\)\(.*\)\2\(.*\)/a & \2:\1\3\4/ 
# sort singles 
:sort 
     s/:\([^a]*\)a\(.*\)$/:\1\2a/ 
     y/abcdefghijklmnopqrstuvwxyz/zabcdefghijklmnopqrstuvwxy/ 
     /^a/ !b sort 

# clean and print 
     s/..// 
     s/:/ /p 
     }' YourFile 

POSIX 그렇게 --posix GNU에 나오지도 나오지도 나오지