Не повторяйтесь!, лол, хорошо, я пытаюсь посмотреть, смогу ли я объединить мои 2 источника awk рабочих процессов github в 1. Я пробовал несколько вещей, но по какой-то причине я продолжал получать странные столбцы. задним числом я мог бы присваивать, а не сравнивать переменные. Решил не засорять вопрос битым кодом.

Awk запускается как git diff-tree -r --no-commit-id --name-status HEAD | awk -f .github/files/changed.awk, без параметров. Вывод 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

Как бы вы его дедуплицировали и улучшили?

-3
xenoterracide 18 Мар 2021 в 07:16
 – 
Kusalananda
16 Мар 2021 в 23:04

2 ответа

Лучший ответ

С некоторыми улучшениями и дедупликацией двух частей в одну.

$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
}
1
αғsнιη 17 Мар 2021 в 10:23

Итак, у вас есть один ввод (или файл, результат 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
      }
    '
0
Isaac 18 Мар 2021 в 23:38