How do we delete all carriage returns after a particular string using sed inside a K Shell?
e.g. I have a text file named file1 below:
$ more file1
Group#=1 User=A
Role=a1
Group#=2 User=B
Role=a1
Role=b1
Group#=3 User=C
Role=b1
I want the carriage returns to be delete on the line which starts with "Group" to have the below:
Group#=1 User=A Role=a1
Group#=2 User=B Role=a1 Role=b1
Group#=3 User=C Role=b1
Any help will be appreciated.
use \r to find the carriage return and delete it so that you will get the desired output.
vino
January 19, 2006, 8:05am
3
Here is non sed solution.
[/tmp]$ cat replace.ksh
#! /bin/ksh
SAVE=""
while read line
do
if [[ "$line" == *Group* ]] ; then
[[ -n $SAVE ]] && echo "$SAVE" && SAVE=""
SAVE="$line"
elif [[ "$line" == *Role* ]] ; then
SAVE="$SAVE $line"
fi ;
done < txt
# For the last accumulated line
echo "$SAVE"
[/tmp]$ cat txt
Group#=1 User=A
Role=a1
Group#=2 User=B
Role=a1
Role=b1
Group#=3 User=C
Role=b1
[/tmp]$ ./replace.ksh
Group#=1 User=A Role=a1
Group#=2 User=B Role=a1 Role=b1
Group#=3 User=C Role=b1
$ nawk '{ if ( $0 ~ /Group/ && NR > 1 ) { printf "\n"; } printf $0; } END { printf "\n"; }' datafile
Group#=1 User=A Role=a1
Group#=2 User=B Role=a1 Role=b1
Group#=3 User=C Role=b1
Thanks everyone! I have another question.
I have a text file file1 below:
$ more file1
Group#=G1
Role=a1 Role#=[001]
User=Adam
User=Ben
Role=b1 Role#=[002]
User=Carl
Group#=G2
Role=a1 Role#=[001]
User=Ben
Role=c1 Role#=[003]
User=Carl
Group#=G3
Role=c1 Role#=[003]
User=Adam
...and I want to create a Korn shell that would create the desired output below (Group,Role,User) when I ran the shell using the input file1:
G1,a1,Adam
G1,a1,Ben
G1,b1,Carl
G2,a1,Ben
G2,c1,Carl
G3,c1,Adam
I first thought of making it one group per line using the awk command below :
$ awk '{ if ( $0 ~ /Group/ && NR > 1 ) { printf "\n"; } printf $0; } END { printf "\n"; }' file1
Group#=G1 Role=a1 Role#=[001] User=Adam User=Ben Role=b1 Role#=[002] User=Carl
Group#=G2 Role=a1 Role#=[001] User=Ben Role=c1 Role#=[003] User=Carl
Group#=G3 Role=c1 Role#=[003] User=Adam
I not sure what to do after this:(
Any help will be appreciated.
vino
January 20, 2006, 4:29am
6
You need a KSH script or an awk script ?
Here is a ksh script.
[/tmp]$ cat steve.ksh
#! /bin/ksh
while read line
do
if [[ "$line" == *Group* ]] ; then
GROUP=""
ROLE=""
USER=""
GROUP=${line##*=}
elif [[ "$line" == *Role* ]] ; then
USER=""
ROLE=${line#*=}
ROLE=${ROLE%% *}
elif [[ "$line" == *User* ]] ; then
USER=${line##*=}
fi ;
[[ -n $GROUP && -n $ROLE && -n $USER ]] && echo "$GROUP,$ROLE,$USER"
done < text
[/tmp]$ ./steve.ksh
G1,a1,Adam
G1,a1,Ben
G1,b1,Carl
G2,a1,Ben
G2,c1,Carl
G3,c1,Adam
[/tmp]$
Thank you very much vino!
I had to make all the double equals signs "==" to a single equals sign "=" to get it work. and it worked great!
By the way could you tell me what the codes below which was in your script is doing?
##*=
%% *
-n
Also if there's a awk solution please tell me if you can.
cheers
Steve
vino
January 23, 2006, 1:34am
8
Why ? How did the results differ in both the cases ?
From man ksh
${name#pattern}, ${name##pattern}
If pattern matches the beginning of the value of parameter name,
the matched text is deleted from the result of substitution. A
single # results in the shortest match, two #?s results in the
longest match.
${name%pattern}, ${name%%pattern}
Like ${..#..} substitution, but it deletes from the end of the
value.
From man test
[-n] STRING
the length of STRING is nonzero
Thanks vino!
When I ran the shell with double equal signs it gave me the error below:
$ ./steve.ksh text
./steve.ksh: syntax error at line 5 : `==' unexpected
$ more steve.ksh
#! /bin/ksh
while read line
do
if [[ "$line" == *Group* ]] ; then
GROUP=""
ROLE=""
USER=""
GROUP=${line##*=}
elif [[ "$line" == *Role* ]] ; then
USER=""
ROLE=${line#*=}
ROLE=${ROLE%% *}
elif [[ "$line" == *User* ]] ; then
USER=${line##*=}
fi ;
[[ -n $GROUP && -n $ROLE && -n $USER ]] && echo "$GROUP,$ROLE,$USER"
done < $1
But with single equal sign:
$ steve2.ksh text
G1,a1,Adam
G1,a1,Ben
G1,b1,Carl
G2,a1,Ben
G2,c1,Carl
G3,c1,Adam
$ more steve2.ksh
#! /bin/ksh
while read line
do
if [[ "$line" = *Group* ]] ; then
GROUP=""
ROLE=""
USER=""
GROUP=${line##*=}
elif [[ "$line" = *Role* ]] ; then
USER=""
ROLE=${line#*=}
ROLE=${ROLE%% *}
elif [[ "$line" = *User* ]] ; then
USER=${line##*=}
fi ;
[[ -n $GROUP && -n $ROLE && -n $USER ]] && echo "$GROUP,$ROLE,$USER"
done < $1
aigles
January 23, 2006, 3:24am
10
== is no'nt a valid operator but some implementations accep it.
You can also use case statement :
#! /bin/ksh
while read line
do
case "$line" in
*Group*)
GROUP=${line##*=}
ROLE=""
USER=""
;;
*Role*)
ROLE=${line#*=}
ROLE=${ROLE%% *}
USER=""
;;
*User*)
USER=${line##*=}
[[ -n $GROUP && -n $ROLE && -n $USER ]] && echo "$GROUP,$ROLE,$USER"
;;
esac
done < $1
Jean-Pierre.
Thanks aigles!
BTW can this be done by awk with less lines of code?
Ygor
January 23, 2006, 10:15pm
12
Using awk...
awk 'BEGIN{FS="[ =]";OFS=","}
$1=="Group#"{g=$2}
$2=="Role"{r=$3}
$2=="User"{print g,r,$3}' file1
Thanks Ygor.
I have another question.
I have two text files below:
$ more list1.txt
TopGroup1 User1 Role1
TopGroup1 User1 Role2
TopGroup2 User1 Role1
TopGroup2 User2 Role3
$ more list2.txt
TopGroup1 SubGroup1 User1
TopGroup1 SubGroup2 User1
TopGroup2 SubGroup3 User1
TopGroup2 SubGroup3 User2
I want create a list below containing "TopGroup SubGroup User Role" by comparing the two files above. (I want the Users in the SubGroups to have the same Roles as the TopGroups)
TopGroup1 SubGroup1 User1 Role1
TopGroup1 SubGroup1 User1 Role2
TopGroup1 SubGroup2 User1 Role1
TopGroup1 SubGroup2 User1 Role2
TopGroup2 SubGroup3 User1 Role1
TopGroup2 SubGroup3 User2 Role3
I am able to get the above result by the K Shell script below but can this be done with less lines of code using awk?
$ more compare
#!/bin/ksh
while read group user role
do
while read group2 subgroup user2
do
if [[ $group = $group2 && $user = $user2 ]] ; then
echo $group $subgroup $user $role
fi;
done < list2.txt
done < list1.txt