대부분의 부정을 반복하려면 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 ~ /\.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 ~ /\.puml$/ &&
$2 !~ /(theme|config)\.puml$/

그 후 스크립트가 $2조치를 취합니다.아니요 D(이것은 삭제를 의미한다고 가정합니다). 또 다른 스크립트는 보완물, $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
      }
    '

관련 정보