Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env -S gawk -f
- # https://gist.github.com/yermulnik/7e0cf991962680d406692e1db1b551e6
- # Tested with GNU Awk 5.1.0, API: 3.0 (GNU MPFR 4.1.0, GNU MP 6.2.1)
- # Usage: /path/to/tf_vars_sort.awk < variables.tf | tee sorted_variables.tf
- # Note: "chmod +x /path/to/tf_vars_sort.awk" before use
- # No licensing; [email protected], 2021-2024
- {
- # skip blank lines at the beginning of file
- if (!resource_type && length($0) == 0) next
- # pick only known Terraform resource definition block types of the 1st level
- # https://github.com/hashicorp/terraform/blob/main/internal/configs/parser_config.go#L92-L230
- switch ($0) {
- # ex: block_type {
- case /^[[:space:]]*(import|locals|moved|removed|terraform)[[:space:]]+{/:
- resource_type = $1
- resource_ident = resource_type "|" block_counter++
- break
- # ex: block_type type_label name_label {
- case /^[[:space:]]*(data|ephemeral|resource)[[:space:]]+("?[[:alnum:]_-]+"?[[:space:]]+){2}{/:
- resource_type = $1
- resource_subtype = $2
- resource_name = $3
- resource_ident = resource_type "|" resource_subtype "|" resource_name
- break
- # ex: block_type name_label {
- case /^[[:space:]]*(check|module|output|provider|variable)[[:space:]]+"?[[:alnum:]_-]+"?[[:space:]]+{/:
- resource_type = $1
- resource_name = $2
- resource_ident = resource_type "|" resource_name
- break
- }
- arr[resource_ident] = arr[resource_ident] ? arr[resource_ident] RS $0 : $0
- } END {
- # exit if there was solely empty input
- # (input consisting of multiple empty lines only, counts in as empty input too)
- if (length(arr) == 0) exit
- # declare empty array (the one to hold final result)
- split("", res)
- # case-insensitive string operations in this block
- # (primarily for the `asort()` call below)
- IGNORECASE = 1
- # sort by `resource_ident` which is a key in our case
- asort(arr)
- # blank-lines-fix each block
- for (item in arr) {
- split(arr[item],new_arr,RS)
- # remove multiple blank lines at the end of resource definition block
- while (length(new_arr[length(new_arr)]) == 0) delete new_arr[length(new_arr)]
- # add one single blank line at the end of the resource definition block
- # so that blocks are delimited with a blank like to align with TF code style
- new_arr[length(new_arr)+1] = RS
- # fill resulting array with data from each resource definition block
- for (line in new_arr) {
- # trim whitespaces at the end of each line in resource definition block
- gsub(/[[:space:]]+$/, "", new_arr[line])
- res[length(res)+1] = new_arr[line]
- }
- }
- # ensure there are no extra blank lines at the beginning and end of data
- while (length(res[1]) == 0) delete res[1]
- while (length(res[length(res)]) == 0) delete res[length(res)]
- # print resulting data to stdout
- for (line in res) {
- print res[line]
- }
- }
Advertisement