awk는 연속된 두 단어의 가장 일반적인 시퀀스를 찾습니다.

awk는 연속된 두 단어의 가장 일반적인 시퀀스를 찾습니다.

"파일"이라는 텍스트 파일이 있습니다. "this is"와 "is this"가 동일한 것으로 간주되는 가장 일반적인 두 단어 시퀀스를 찾으려면 awk를 사용해야 합니다.

예시 텍스트: 내 이름은 이고 이는 다음과 같은 텍스트입니다.

예상 출력: 3입니까?

나는 이 루프를 사용했습니다:

awk 'BEGIN{
    for(i=1;i<NF;i++) 
    a[$i OFS $(i+1)]++
    }' file

왜 이것이 실패하는지 아는 사람이 있습니까?

답변1

파일을 읽지 않기 때문에 코드가 실패합니다. 특수 BEGIN블록이 실행됩니다.앞으로명령줄에 이름이 지정된 첫 번째 입력 파일도 읽기 위해 열립니다( END마지막 파일 다음 블록도 마찬가지). 또한 코드의 출력이 없습니다.

다른 사람들은 이미 자신만의 솔루션을 제공했으므로 귀하의 코드를 가져와 약간 수정하겠습니다.

  1. 입력의 각 줄에 대해 실행되도록 일반 블록에서 코드를 실행합니다.
  2. 블록을 사용하여 END배열에서 가장 일반적인 단어 조합을 찾고 모든 입력이 처리된 후 출력합니다.
  3. 각 쌍의 단어가 항상 사전순으로 사용되는지 확인하세요.
awk '
    {
        for (i = 1; i < NF; i++)
            if ($i < $(i+1)) a[$i OFS $(i+1)]++
            else             a[$(i+1) OFS $i]++
    }
    END {
        for (words in a)
            if (a[words] > a[m]) m = words
        print m, a[m]
    }' file

주어진 입력에 따라 가 인쇄됩니다 is this 3.

또 다른 구현은 파일을 읽는 동안 최대값을 추적한 다음 끝에 인쇄하는 것입니다.

awk '
    {
        for (i = 1; i < NF; ++i) {
            if ($i < $(i+1)) words = $i OFS $(i+1)
            else             words = $(i+1) OFS $i
            if (++count[words] > count[m]) m = words
        }
    }
    END { print m, count[m] }' file

배열에 대해 걱정하지 마십시오.

awk '{ for (i = 1; i < NF; ++i) if ($i < $(i+1)) print $i, $(i+1); else print $(i+1), $i }' file | sort | uniq -c | sort -n | tail -n 1

즉, awk단어 조합 생성(한 줄에 하나씩)을 사용한 다음 이를 정렬하고 각각의 발생 횟수를 얻은 다음 정렬합니다.이것들(개수 기준) 가장 높은 개수를 선택하세요. 큰 데이터를 호출하고 sort이메일과 같은 작은 데이터를 실행하는 것은 비용이 많이 들지만 충분합니다.

답변2

노력하다:

gawk '{
       for (i=2; i<=NF; i++) {
           delete arr; split($(i-1) "\n" $i, arr);
           asort(arr); s[arr[1] FS arr[2]]++
       };
     }
END { for(x in s) print s[x], x }' infile |sort -nr
3 is this
2 my name
1 our text
1 is text
1 is our
1 is name

split()이 함수는 공백(탭/공백)으로 구분된 문자열 쌍을 배열에 추가 arr하지만 각 문자열은 별도의 줄에 있습니다 \n.

asort()함수는 arr해당 배열을 정렬합니다. 그런 다음 정렬된 문자열 쌍으로 키를 사용하여 호출되는 다른 배열에 결과를 추가하고 s, 다시 발생하면 동일한 문자열 쌍마다 값이 증가합니다.

delete arrarr다음 필드 쌍을 처리하기 위해 배열을 삭제합니다 .

END배열 요소를 반복 s하고 쌍 자체와 함께 표시된 각 요소 쌍의 개수를 인쇄한 후 결과 sort -nr가 정렬되어 가장 많이 반복되는 문자열 쌍을 제공합니다.

is this참고: 결과에서는 대부분 또는 전체 가 있는지 알려주지 않고 그 중 하나만 알려주며 이 예의 결과로 this is모든 정렬된 결과만 알려줍니다 .is this

답변3

@kusalananda가 지적했듯이 가장 큰 실수는 모든 코드를 BEGIN 블록에 넣는 것입니다. 따라서 "this is" and "is this" are considered equal in our count.입력에 나타나는 상대적 순서에 관계없이 만나는 모든 단어 쌍이 특정(정렬된) 순서로 저장되도록 보장하려면 다음과 같은 작업을 수행해야 합니다.

awk '
{
    for(i=1; i<NF; i++) {
        pair = ($i > $(i+1) ? $i OFS $(i+1) : $(i+1) OFS $i)
        c = ++cnt[pair]
        max = (max > c ? max : c)
    }
}
END {
    for (pair in cnt) {
        c = cnt[pair]
        if ( c == max ) {
            print pair, c
        }
    }
}
' file
this is 3

관련 정보