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