|
| 1 | +#!/usr/bin/env bash |
| 2 | +# Usage: ./yamlParser.sh <yaml_file> <key_path> |
| 3 | +# Example: ./yamlParser.sh config.yaml '.http.tls.keyFile' |
| 4 | + |
| 5 | +yaml_file="$1" |
| 6 | +key_path="$2" |
| 7 | + |
| 8 | +if [[ -z "$yaml_file" || -z "$key_path" ]]; then |
| 9 | + echo "Usage: $0 <yaml_file> <key_path>" |
| 10 | + exit 1 |
| 11 | +fi |
| 12 | + |
| 13 | +if [[ ! -f "$yaml_file" ]]; then |
| 14 | + echo "File not found: $yaml_file" |
| 15 | + exit 1 |
| 16 | +fi |
| 17 | + |
| 18 | +key_path="${key_path#.}" |
| 19 | +keys_for_awk=$(echo "$key_path" | tr '.' ' ') |
| 20 | + |
| 21 | +awk -v keys="$keys_for_awk" ' |
| 22 | +BEGIN { |
| 23 | + # Split the input key path string into an array |
| 24 | + split(keys, path, " ") |
| 25 | + path_len = length(path) |
| 26 | + current_level = 1 |
| 27 | + # indent_levels array stores the indentation length for each level |
| 28 | + # Set indent_levels[0] to -1 to prevent errors in the first level check |
| 29 | + indent_levels[0] = -1 |
| 30 | +} |
| 31 | +
|
| 32 | +# Skip empty lines or lines that are purely comments |
| 33 | +/^[[:space:]]*#|^[[:space:]]*$/ { next } |
| 34 | +
|
| 35 | +{ |
| 36 | + # Match indentation at the start of the line and the key |
| 37 | + # m[1] is the indentation, m[2] is the key |
| 38 | + if (match($0, /^([[:space:]]*)([^:]+):/, m)) { |
| 39 | + indent = length(m[1]) |
| 40 | + key = m[2] |
| 41 | +
|
| 42 | + # Adjust current level by comparing current indentation with the previous level |
| 43 | + # If current indent is less than or equal to previous level, step back in hierarchy |
| 44 | + while (indent <= indent_levels[current_level - 1]) { |
| 45 | + current_level-- |
| 46 | + } |
| 47 | +
|
| 48 | + # If the key on the current line matches the key in the path we are looking for |
| 49 | + if (key == path[current_level]) { |
| 50 | + # Record the indentation of the current level |
| 51 | + indent_levels[current_level] = indent |
| 52 | +
|
| 53 | + # If we have matched the last level of the path, extract and process its value |
| 54 | + if (current_level == path_len) { |
| 55 | + # Extract everything after the colon as the initial value |
| 56 | + value = $0 |
| 57 | + sub(/^[^:]+:[[:space:]]*/, "", value) |
| 58 | +
|
| 59 | + # --- Clean the value --- |
| 60 | + # 1. Remove comments at the end of the line |
| 61 | + sub(/[[:space:]]*#.*$/, "", value) |
| 62 | + # 2. Remove all leading/trailing whitespace |
| 63 | + gsub(/^[[:space:]]+|[[:space:]]+$/, "", value) |
| 64 | + # 3. Remove double quotes surrounding the value |
| 65 | + gsub(/^"|"$/, "", value) |
| 66 | +
|
| 67 | + print value |
| 68 | + exit |
| 69 | + } |
| 70 | +
|
| 71 | + # If not the last level, increment level and continue matching downwards |
| 72 | + current_level++ |
| 73 | + } |
| 74 | + } |
| 75 | +} |
| 76 | +' "$yaml_file" |
0 commit comments