user1116377
user1116377

Reputation: 699

Bash - read a properties file and merge lines by keys

I have a properties file of the form:

group1=A,B,C
group1_count=10

# zero or more number of empty lines

group2=A,E
group2_count=1
...
...

I would like to read the file in a bash script and print something like: group_name:group_count:group_items:

group1:10:A,B,C
group2:1:A,E

Upvotes: 0

Views: 124

Answers (3)

Jetchisel
Jetchisel

Reputation: 7801

On a Mac there should be ed by default.

The script.ed

g/^$/d
g/./+1s/.*=\(.*\)/ \1/
g/./;+1j\
s/^\([^=]*\)\([^ ]*\)\(.*\)$/\1\3\2/\
s/[=  ]/:/g
,p
Q

Now run

ed -s file.txt < script.ed

Upvotes: 0

anubhava
anubhava

Reputation: 785601

You may try this awk also:

awk -F= -v OFS=: 'NF!=2 {next} sub(/_count$/, "", $1)
{print $1, $2, grp[$1]} {grp[$1] = $2}' file

group1:10:A,B,C
group2:1:A,E

Upvotes: 2

Charles Duffy
Charles Duffy

Reputation: 295650

If your input is sorted (removing the need to group items that are presented out-of-order -- which would call for data structures bash 3 doesn't support), you can do something like the following:

#!/usr/bin/env bash
 
name=
while IFS= read -r line; do
  [[ $line = *"#"* ]] && line=${line%%"#"*} # strip comments
  [[ $line ]] || continue # skip empty lines
  [[ $line =~ ^[[:space:]]+$ ]] && continue # skip lines with only whitespace
  new_name=${line%%_*}; new_name=${new_name%%=*}
  if [[ $new_name != "$name" ]]; then
    if [[ $name ]]; then
      echo "${name}:${count}:${groups}"
    fi
    name=$new_name; count=; groups=
  fi
  case $line in
    *_count=*) count=${line#*_count=} ;;
    *=*)       groups=${line#*=} ;;
  esac
done
echo "${name}:${count}:${groups}"

See this running at https://ideone.com/nrpfLO

Upvotes: 2

Related Questions