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この行をとして保存し、次のtype2行(group「定義済み」と呼ばれる$0)を取得します。

awkループ中に配列要素が乱れないようにするには、2つの配列をトリックとして使用します。

  • 整数キーを持つ配列には、次の行で構成されるa配列のキーが格納されます。btypegroup
  • 配列はb特定のキーに対して収集された文字列を保持します。

配列のキーの組み合わせが存在しない場合は、b2つの新しい配列要素を作成します。文字列はtype最初に見つかったときにのみ保存されます(出力にバグがある場合は-blockを削除してにif-else if-else置き換えます)。b[key]=type group"\n"$0b[key]=type"\n"group"\n"$0

キーが存在する場合は、「定義」文字列が既存の配列値に追加されます。

このセクションでは、END配列順序を使用して配列値を印刷し、区切り線を使用します。ba

(入力をファイルとして保存しましたが、必要に応じてfileコマンド出力をこのawkスクリプトにパイプすることができます。)curl

出力:

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

修正する

カテゴリリストを使用するには、カテゴリごとに1行ずつテキストファイルにカテゴリを追加します。

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

おすすめ記事