Radius
Radius

Reputation: 348

Parse commitlog

I have a certain script that builds several projects and after each build it outputs a log of the commits, so, after one run it may look like this:

project_1 2015-09-09
------------------
a
b
c
d

project_2 2015-09-09
------------------
1
2
3
4

Then after an hour or so it will build all the projects that have changes so the file would now look like this

project_1 2015-09-09
------------------
a
b
c
d

project_2 2015-09-09
------------------
1
2
3
4
project_1 2015-09-09
------------------
a1
b1
c1
d1

project_2 2015-09-09
------------------
11
22
33
44

project_3 2015-09-09
------------------
11a
22a
33a
44a

I would like to parse the file to collapse sections with the same name into one so it would look like this:

project_1 2015-09-09
------------------
a
b
c
d
a1
b1
c1
d1

project_2 2015-09-09
------------------
1
2
3
4
11
22
33
44

project_3 2015-09-09
------------------
11a
22a
33a
44a

project_1 2015-09-10
------------------
aasd
bddd
cddd
ddd
a1dddd
b1ddd
c1ddd
d1dd

Upvotes: 0

Views: 51

Answers (4)

Fritz G. Mehner
Fritz G. Mehner

Reputation: 17198

Almost pure Bash. Collect project lines in an associative array, sort keys, and write projects in sorted order

declare -A array
declare sep="------------------"

while read line; do
  if [[ $line =~ ^project_ ]] ; then
    key="$line"
  else
    [[ $line =~ ^(---|$) ]] || array[$key]+="$line"$'\n'
  fi
done  < "$infile"

readarray -t idx < <(for a in "${!array[@]}"; do echo "$a"; done | sort -k2 )

for key in "${idx[@]}"; do
  printf "%s\n%s\n%s\n" "$key" "$sep" "${array[$key]}"
done

Upvotes: 1

Renaud Pacalet
Renaud Pacalet

Reputation: 29393

Not very elegant but doing the job:

grep project_ data.txt | sort | uniq | while read p
do
    awk -v p="$p" 'BEGIN{print p; print "------------------"}
        $0==p {b=1;next} /^$/||/^project_/ {b=0} b>1 {print}
        b>0 {b+=1}' data.txt
done

The grep sort uniq extracts the uniquified sorted list of projects. The list is then passed to awk, one project at a time. awk selects the relevant data and prints the common header only once, skipping empty lines.

Upvotes: 0

Mahesh Kharvi
Mahesh Kharvi

Reputation: 399

The projects are not in order

awk '/project_/{proj=$0;next}
/----/{next}
{a[proj]=a[proj]"\n"$0}
END{for(i in a){printf("%s\n------------------%s\n",i,a[i])}}' logfile
  • if line matches project_, assign $0 to variable proj.
  • Skip lines matching ------.
  • Store values of each project under array a with proj as index.
  • At the end, loop through the array and display

Upvotes: 1

Reuben L.
Reuben L.

Reputation: 2859

This is an inelegant answer that probably doesn't answer your question fully. But maybe it can push you in the right direction.

cat logfile |  grep  -Ev "\-{2,}" | while read line;
do 
  new=$(echo $line | grep -Ec [0-9]{4}-[0-9]{2}-[0-9]{2}); 
  if [ $new -ge 1 ]
    then pro=$line; 
  else
    echo $pro $line; 
  fi; 
done | sort -k1,2 | 
awk '{if (old!=$1$2) print "\n"$1" "$2"\n--------"; if($3) print $3; old = $1$2}'

Upvotes: 1

Related Questions