ほとんどの否定を繰り返すには、awk

ほとんどの否定を繰り返すには、awk

繰り返さないでください! 、ハハ、わかりました。 2つのgithubワークフローawkソースを1つにマージできるかどうかを知りたいです。いくつか試してみましたが、何らかの理由で常に奇妙な列の内容で終わりました。振り返ってみると、変数を比較するのではなく、割り当てをしたかもしれません。私はこの問題を破損したコードで汚染しないことにしました。

git diff-tree -r --no-commit-id --name-status HEAD | awk -f .github/files/changed.awkawkはオプションなしで実行されています。出力はgit diff-tree次のとおりです

( cat << EOF
A       .config/plantuml/theme.puml
M       .github/workflows/main.yml
M       .github/workflows/plantuml.yml
M       README.md
A       app/gradle.lockfile
A       authn/gradle.lockfile
A       docs/README.md
A       docs/domain-model/README.md
A       docs/domain-model/user.md
A       docs/domain-model/user.puml
A       docs/domain-model/foo.puml
M       settings.gradle.kts
D       user.puml
D       foo.puml
EOF
) | awk -f file.awk

これが私が思いついたものです。

$2 ~ /\.puml$/ &&
$2 !~ /(theme|config)\.puml$/ &&
$1 !~ /^D$/ {
  changed[++n]=$2
}
END {
  for ( i in changed ) result = result " " changed[i]
  printf "::set-output name=changed-files::%s\n", result
  printf "::warning::changed-files %s\n", result
}

出力

::set-output name=changed-files:: docs/domain-model/user.puml docs/domain-model/foo.puml
::warning::changed-files docs/domain-model/user.puml docs/domain-model/foo.puml
$2 ~ /\.puml$/ &&
$2 !~ /(theme|config)\.puml$/ &&
$1 ~ /^D$/ {
  split($2, fn, ".")
  changed[++n]=fn[1] ".svg"
}
END {
  for ( i in changed ) result = result " " changed[i]
  printf "::set-output name=removed-files::%s\n", result
  printf "::warning::removed-files %s\n", result
}

出力

::set-output name=removed-files:: user.svg foo.svg
::warning::removed-files  user.svg foo.svg

これは現在のワークフローファイルそれが役立つなら。注:変更はawk -f現在破損している分岐で行われました。完了したら削除して圧縮します。

目標は出力を得ることです。似たような次に。私気にしないで行の順序に関して、リストのスペースは、およびgit addシェルに渡すことができる場合にのみgit rm重要です。plantuml

# adding empty lines between just for readability here, comments do nott matter either
::set-output name=changed-files:: docs/domain-model/user.puml docs/domain-model/foo.puml
::warning::changed-files docs/domain-model/user.puml docs/domain-model/foo.puml

::set-output name=removed-files:: user.svg foo.svg
::warning::removed-files  user.svg foo.svg

どのように重複を排除して改善できますか?

答え1

2つの部分を1つに改善し、重複排除した後。

$2 ~ /\.puml$/ && $2 !~ /(theme|config)\.puml$/ \
{ if($1 !~ /^D$/) { result1= (result1==""? "" : result1 " ") $2 } else {
      split($2, fn, ".")
      result2=(result2==""? "" : result2 " ") fn[1] ".svg"
  }
}
END {
  printf "::set-output name=files::%s\n::warning::%s\n", result1, result1
  printf "::set-output name=files::%s\n::warning::%s\n", result2, result2
}

答え2

だからあなたは一つ入力(またはファイル、gitの結果)

A       .config/plantuml/theme.puml
M       .github/workflows/main.yml
M       .github/workflows/plantuml.yml
M       README.md
A       app/gradle.lockfile
A       authn/gradle.lockfile
A       docs/README.md
A       docs/domain-model/README.md
A       docs/domain-model/user.md
A       docs/domain-model/user.puml
A       docs/domain-model/foo.puml
M       settings.gradle.kts
D       user.puml
D       foo.puml

そして二つawkスクリプトはこの入力に似ていますが、他の操作を実行します。

あなたの目標は、このスクリプトが実行する必要があるタスクの数をできるだけ減らすことを前提としています。

最初の2行はまったく同じです。

$2 ~ /\.puml$/ &&
$2 !~ /(theme|config)\.puml$/

その後、スクリプトはアクション$2を取ります。いいえ D(これは削除を意味すると仮定します)。もう1つのスクリプトは、補足、$2つまり対処を行いますD。次のようにエンコードできます。

{ if ( $1 ~ /^[D]$/ ) then { print "Deleted" } else { print "Changed" } }

またはより詳細な選択が必要な場合:

{ if ( $1 ~ /^[D]$/  ) then { print "Deleted" } 
  if ( $1 ~ /^[MA]$/ ) then { print "Changed" } }

必要なのはスペースで区切られたファイルのリストなので、実際に各ファイルを配列に保存する必要はありません。

これは各入力ラインのループ内で行うことができます(メモリが少なく高速です)。

{ if ( $1 ~ /^[D]$/ ) then { deleted = deleted " " $2 } 
  if ( $1 ~ /^[A]$/ ) then { changed = changed " " $2 } }

もちろん、一致は正規表現ではなく正確な文字列(より高速)にすることができ、変更された大文字と小文字から拡張子なしでファイル名を抽出する必要があります。

{ if ( $1 == "D" ) then { deleted = deleted " " $2 } 
  if ( $1 == "A" ) then { sub( /\.[^.]+$/, "", $2 ) ; 
                          changed = changed " " $2 ".svg"
                        }
}

すべてのアイデアをテストするシェルスクリプトは次のとおりです。

#!/bin/bash

a='\
A       .config/plantuml/theme.puml
M       .github/workflows/main.yml
M       .github/workflows/plantuml.yml
M       README.md
A       app/gradle.lockfile
A       authn/gradle.lockfile
A       docs/README.md
A       docs/domain-model/README.md
A       docs/domain-model/user.md
A       docs/domain-model/user.puml
A       docs/domain-model/foo.puml
M       settings.gradle.kts
D       user.puml
D       foo.puml
'

printf '%s\n' "$a" | awk '
      $2  ~ /\.puml$/ &&
      $2 !~ /(theme|config)\.puml$/ {  
             if ( $1 == "D" ) { deleted = deleted " " $2 }
             if ( $1 == "A" ) { sub(/\.[^.]+$/, "", $2);
                                changed = changed " " $2 ".svg"
             }
      }
      END {
             printf "::set-output name=removed-files::%s\n", deleted
             printf "::warning::removed-files %s\n", deleted
             printf "::set-output name=changed-files::%s\n", changed
             printf "::warning::changed-files %s\n", changed
      }
    '

関連情報