split files to key value pair

Viewed 137
Input file
           - name: APPENV
             value: STAGING
           - name: ELASTICSEARCH_USER
             value: elastic
           - name: WRITE_LOGS_TO_ELASTICSEARCH
             value: "true"
           - name: version
             value: "5"

Expected output:

APPENV: STAGING
ELASTICSEARCH_USER: elastic
WRITE_LOGS_TO_ELASTICSEARCH: "true"
version: "5"

tried awk -F "e:" '{print $2}' filename to abstract only key and value, but need to align this as above output. Any help would be appreciated

4 Answers

With your shown samples and attempts, please try following awk code.

awk 'BEGIN{OFS=": "} /^- name:/{val=$NF;next} {print val,$NF}' Input_file

Explanation: simple explanation would be, firstly setting OFS(output field separator) as : for all lines. In main awk program checking if line starts from - name: then assign last field value to variable val and using next will skip all further awk program statements from here. When this condition(line starts from - name:) is NOT TRUE then printing val and last field of that line.



EDIT: In case your Input_file really has spaces before - name: then try following code.

awk 'BEGIN{OFS=": "} /^[[:space:]]+- name:/{val=$NF;next} {print val,$NF}' Input_file

This works:

awk '
sub(/^[[:space:]]+- name: /, ""){n=$0}
sub(/^[[:space:]]+value: /, ""){print n": "$0}'

Match and remove the name: /value: labels, and print the remainder of both lines on a single line.

This looks like a YAML file? In that case you should probably use a dedicated parser, e.g. Mike Farah's yq :

yq e '.[] | .name + ": " + .value' infile

Output:

APPENV: STAGING
ELASTICSEARCH_USER: elastic
WRITE_LOGS_TO_ELASTICSEARCH: true
version: 5

Tested with yq version 4.14.1.

Also with awk:

awk -v FS=': ' '!(NR%2){s=$2} (NR%2){if (s) print s ":", $2}' file
APPENV: STAGING
ELASTICSEARCH_USER: elastic
WRITE_LOGS_TO_ELASTICSEARCH: "true"
version: "5"
Related