Skip to content
Advertisement

need help on shell script for expected output

I have an input file called input.txt like this:

powerOf|creating new file|failure
creatEd|new file creating|failure
powerAp|powerof server|failureof file

I extract the text up to just before the fist capital letter in the first field and store those snippets in output.txt:

power
creat

I used the sed command to separate out the values and it’s working fine.

From the output file (output.txt), I need to grep from the first field, and output should be like below:

Power
power:powerOf|creating new file|failure,powerAp|powerof server|failureof file
creat
creat:creatEd|new file creating|failure

I have tried a few ways but I’m not getting the expected output.

I tried the following but I’m getting duplicate entries:

cat input.txt | cut -d '|' f1 >> input1.txt
cat input1.txt | s/([a-z])([A-Z])/1 2/g >> output.txt
while read -r line;do
  echo $ line
  cat input.txt |cut -d ‘|’ f1|grep $line >> output1. txt
done< "output.txt"

I have 20000 lines in the input file. I don’t know why I am getting duplicates the output. What am I doing wrong?

Advertisement

Answer

Bash solution:

#!/bin/bash
keys=()
declare -A map
while read line; do
    key=$(echo ${line} | cut -d | -f1 | sed -e 's/[[:upper:]].*$//')
    if [[ -z "${map[$key]}" ]]; then
        keys+=(${key})
        map[$key]="${line}"
    else
        map[$key]+=",${line}"
    fi
done

for key in ${keys[*]}; do
    echo "${key}"
    echo "${key}:${map[$key]}"
done

exit 0

Maybe a Perl solution is acceptable for OP too:

#!/usr/bin/perl
use strict;
use warnings;

my @keys;
my %map;
while (<>) {
    chomp;
    my($key) = /^([[:lower:]]+)/;
    if (not exists $map{$key}) {
        push(@keys, $key);
        $map{$key} = [];
    }
    push(@{ $map{$key} }, $_);
}

foreach my $key (@keys) {
    print "$keyn";
    print "$key:", join(",", @{ $map{$key} }), "n";
}


exit 0;

Test with your given input:

$ perl dummy.pl <dummy.txt
power
power:powerOf|creating new file|failure,powerAp|powerof server|failureof file
creat
creat:creatEd|new file creating|failure

UPDATE after OP has re-stated the original problem. Solution for the first loop that only includes the 2nd column of the input instead of the whole line:

    message=$(echo ${line} | cut -d | -f2)
    if [[ -z "${map[$key]}" ]]; then
        keys+=(${key})
        map[$key]="${message}"
    else
        map[$key]+=",${message}"
    fi

Test with your given input:

$ perl dummy.pl <dummy.txt
power
power:creating new file,powerof server
creat
creat:new file creating
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement