awk를 사용하여 목록 정렬

awk를 사용하여 목록 정렬
#!/bin/bash

PASTE=$(xclip -o)

curl -s https://website.com/$PASTE | dos2unix | grep -A3 '<td class="hidden-xs"' | sed 's/<[^>]*//1g; s/>//g; s/  //g; s/\\r//g; /^$/d; s/--/-/g; s/&#246;/ö/g; s/&#252;/ü/g; s/&#231;/ç/g' | awk '!/^Genel/ || !f++'

다음과 같은 결과가 생성됩니다.

General
hit
definition 1
-
General
hit
definition 2
-
... 
-
Idiom
hit the sack
Definition 
-
Idiom
hit the buffers
Definition 1
-
Idiom
hit the buffers
Definition 2

나는 그것을 분류하려고 노력했고 다음과 같은 결과를 얻었습니다.

General
hit
definition 1
definition 2
definition ...
-
Idiom
hit the sack
Definition 
-
hit the buffers
Definition 1
Definition 2

답변1

사용 awk:

awk '
$0=="General" || $0=="Idiom"{
  type=$0;  getline
  group=$0; getline

  key=type","group  
  if (key in b){
    b[key]=b[key]"\n"$0
  }
  else {
    if (type=="General" && !isfirstgeneral){
      type=type"\n"; isfirstgeneral=1
    }
    else if (type=="Idiom" && !isfirstidiom){
      type=type"\n"; isfirstidiom=1
    }
    else {
      type=""
    }
    a[++cnt]=key
    b[key]=type group"\n"$0
  }
}
END{
  for (i=1;i<=cnt;i++){
    print b[a[i]]
    if (i<cnt) print "-"
  }
}' file

행이 General또는 인 경우 Idiom이 행을 로 저장 type하고 다음 두 행( group, "정의된" 이라고 함 $0)을 가져옵니다.

awk루프할 때 배열 요소가 무질서해지는 것을 방지하려면 두 개의 배열을 트릭으로 사용하십시오 .

  • 정수 키가 있는 배열은 다음 행으로 구성된 a배열의 키를 저장합니다.btypegroup
  • 배열은 b특정 키에 대해 수집된 문자열을 보유합니다.

배열의 키 조합이 존재하지 않는 경우 b두 개의 새 배열 요소를 만듭니다 . 문자열은 type처음 발견될 때만 저장됩니다(출력에 버그가 있는 경우 -block을 제거 하고 로 if-else if-else바꾸십시오 ).b[key]=type group"\n"$0b[key]=type"\n"group"\n"$0

키가 존재하는 경우 "정의" 문자열이 기존 배열 값에 추가됩니다.

이 섹션에서는 END배열 순서를 사용하여 배열 값을 인쇄한 다음 구분선을 사용합니다.ba

(입력을 file 로 저장했지만 원하는 경우 file명령 출력을 이 awk 스크립트로 파이프할 수 있습니다 .)curl

산출:

General
hit
definition 1
definition 2
-
Idiom
hit the sack
Definition
-
hit the buffers
Definition 1
Definition 2

고쳐 쓰다

카테고리 목록을 사용하려면 카테고리당 한 줄씩 텍스트 파일에 카테고리를 추가하세요.

categories.txt:

General
Idiom
Computer
What ever

스크립트를 다음으로 변경하세요.

awk '
NR==FNR{
  cat[$0]; next
}
$0 in cat{
  type=$0;  getline
  group=$0; getline

  key=type","group  
  if (key in b){
    b[key]=b[key]"\n"$0
  }
  else {
    a[++cnt]=key
    b[key]=group"\n"$0
  }
}
END{
  for (i=1;i<=cnt;i++){
    # print first occurrence of category
    catname=a[i]
    sub(/,.*/, "", catname)
    if (catname in cat){
      print catname
      delete cat[catname]
    }

    print b[a[i]]
    if (i<cnt) print "-"
  }
}' categories.txt file

답변2

awk연관 배열의 사용은 약간 뻔뻔스럽습니다...

awk '$0=="General"||$0=="Idiom"{
    cat=$0;getline; def=$0; getline;
    (cat=="General")?gen[def]=gen[def]"\n"$0:idi[def]=idi[def]"\n"$0
}END{
    print "General";for (g in gen) print g, gen[g]"\n-";
    print "Idioms";for (i in idi) print i, idi[i]"\n-"
}' file

산출:

General
hit 
definition 1
definition 2
-
Idioms
hit the buffers 
Definition 1
Definition 2
-
hit the sack 
Definition
-

물론 이는 모든 정의가 "한 줄"이라고 가정합니다.

카테고리 더보기카테고리가 나타나는 순서에 대해 걱정하지 마세요...

awk '{
    cat=$0; getline; phr=$0;getline; def=$0; getline;
    cats[cat];defs[phr]=cat;txt[phr]=txt[phr]"\n"def
}END{
    for (c in cats) {
        print c":"; for (d in defs) {
            if (defs[d]==c) print d, txt[d]"\n-"
        }
    }
}' file

입력하다

General
hit
Strike a blow.
-
General
hit
A successful search result. 
-
Idiom
hit the sack
Go to bed.
-
Idiom
hit the buffers
Reach the end of the line.
-
Idiom
hit the buffers
Reach the limit.
-
Bananas
Banana
A Banana

산출

Bananas:
Banana 
A Banana
-
Idiom:
hit the buffers 
Reach the end of the line.
Reach the limit.
-
hit the sack 
Go to bed.
-
General:
hit 
Strike a blow.
A successful search result. 
-

카테고리 출력을 찾은 것과 동일한 순서로 제어하려면 카테고리를 열거하거나 |모든 s에 대해 cat(예를 들어)로 구분된 문자열을 생성 하고 split이를 열거형 배열에 넣은 다음 다른 배열에 대한 반복자.

이는 실제로 항목의 4줄 순서에 따라 달라집니다.

관련 정보