sikku
July 5, 2011, 4:52am
1
Hi,
I have two strings eg:
string1=abc|def|hij
string2=12|13|14
I want a new string with
string3="abc:12 def:13 hij:14"
I am using shell scripting. Is there any method to do this?
I tried using cut command but this wont advance the respective strings.
Can anybody help in this matter?
Not a pure shell solution, however the following works
export string1="abc|def|hij"
export string2="12|13|14"
string3=$(perl -e '@f=split /\|/, $ENV{string1};@s=split /\|/, $ENV{string2};for (0..$#f){print "$f[$_]:$s[$_] "}')
echo $string3
1 Like
sikku
July 5, 2011, 5:26am
3
Thanks.
It runs from the command line, but not from the script file.
Any idea?
I am running this script as
#!/bin/sh
a pure shell (ksh) solution :
#!/usr/bin/ksh
string1='abc|def|hij'
string2='12|13|14'
string3=''
oIFS="${IFS}"
IFS='|'
set -A str1 ${string1}
set -A str2 ${string2}
IFS="${oIFS}"
cnt1=${#str1[*]}
cnt2=${#str2[*]}
(( cnt1 > cnt2 )) && cnt=${cnt1} || cnt=${cnt2}
while (( cnt > 0 ))
do
(( cnt -= 1 ))
string3="${str1[$cnt]}:${str2[$cnt]} ${string3}"
done
string3="${string3# }"
print "${string3}"
Jean-Pierre.
1 Like
sikku
July 5, 2011, 5:55am
5
It worked fine in ksh. Thanks for the help.
But it gives wrong results for strings of different length.
Any idea to restrict it to the smaller string among the both?
paste -d: <(echo $string1 | sed 's/\|/ /g' | xargs -n1) <(echo $string2 | sed 's/\|/ /g' | xargs -n1) | xargs
---------- Post updated at 12:07 PM ---------- Previous update was at 12:06 PM ----------
[ctsgnb@shell ~/sand]$ echo $string1
abc|def|hij
[ctsgnb@shell ~/sand]$ echo $string2
12|13|14
[ctsgnb@shell ~/sand]$ paste -d: <(echo $string1 | sed 's/\|/ /g' | xargs -n1) <(echo $string2 | sed 's/\|/ /g' | xargs -n1) | xargs
abc:12 def:13 hij:14
[ctsgnb@shell ~/sand]$
---------- Post updated at 12:11 PM ---------- Previous update was at 12:07 PM ----------
echo $string1 $string2 | sed 's/\|/ /g' | xargs -n1 | pr -2 -t -s: | xargs
$ echo $string1 $string2 | sed 's/\|/ /g' | xargs -n1 | pr -2 -t -s: | xargs
abc:12 def:13 hij:14
1 Like
Or..
str3=$(echo "$str1 $str2" | sed 's/\(.*\)|\(.*\)|\(.*\) \(.*\)|\(.*\)|\(.*\)/\1:\4 \2:\5 \3:\6/')
sikku
July 5, 2011, 7:21am
8
@ctsgnb Thanks.
Your code also worked.
I have small change in the string2 and want the output in a different way now
string1=abc|def|ghi
string2=123:2|124:1|125:3
the format is like this
string1=<abc>|<abc>
string2=<1234>:<1 to 24>|<1235>:<1 to 24>
Rule is to have same no of tokens in both the strings, but it may vary depending upon who inputs the values.
Need to have check before itself.
I want the output as follows:
string3="123:abc:2 124:def:1 125:ghi:3"
I know its bit complicated, but provided the way you people have given replies it seems to be very easy for you.
I am very weak in scripting, but my boss has given me some work on this and I need to deliver it soon...
Appreciate if you can help.
Thanks for the pr command. And we can shorten your latest post using tr or sed
echo $string1 $string2| sed 's/[ |]/\n/g'| pr -2 -t -s: | xargs
ctsgnb
July 5, 2011, 7:46am
10
@michaelrozar
For me it works better with tr :
[ctsgnb@shell ~/sand]$ echo "$string1 $string2" | sed -e "s/[ |]/\n/g" | pr -2ts: | xargs
abcndefnhijn12n13n14:
[ctsgnb@shell ~/sand]$ echo "$string1 $string2" | tr ' |' '\n' | pr -2ts: | xargs
abc:12 def:13 hij:14
---------- Post updated at 01:46 PM ---------- Previous update was at 01:35 PM ----------
@sikku :
[ctsgnb@shell ~/sand]$ echo "$string1 $string2" | tr ' |' '\n' | pr -2ts: | sed 's/^\([^:]*\):\([^:]*\)/\2:\1/' | xargs
123:abc:2 124:def:1 125:ghi:3
sikku
July 5, 2011, 8:03am
11
@ctsgnb
Dint work for me.
Maybe I am using sun OS?
$ echo $string1
abc|def|hij
$ echo $string2
123:1|124:2|125:3
$ echo "$string1 $string2" | tr ' |' '\n' | pr -2ts: | sed 's/^\([^:]*\):\([^:]*\)/\2:\1/' | xargs
123:abc|def|hij:1|124:2|125:3
I tried with this:
paste -d: <((echo $string2 | sed 's/\|/ /g' | xargs -n1) | cut -f1 -d:) <(echo $string1 | sed 's/\|/ /g' | xargs -n1) <((echo $string2 | sed 's/\|/ /g' | xargs -n1) | cut -f2 -d: ) | xargs
123:abc:1 124:def:2 125:hij:3
Is there any possibility to reduce the code?
ctsgnb
July 5, 2011, 8:12am
12
@sikku , try again separating the option of pr command, and make sure you didn't forget anything in the sed syntax.
echo "$string1 $string2" | tr ' |' '\n' | pr -2 -t -s: | sed 's/^\([^:]*\):\([^:]*\)/\2:\1/' | xargs
---------- Post updated at 02:12 PM ---------- Previous update was at 02:10 PM ----------
then you can pass the statement step by step to see what doesn't behave as expected :
See how the final output is built step by step :
[ctsgnb@shell ~/sand]$ echo "$string1 $string2"
abc|def|ghi 123:2|124:1|125:3
[ctsgnb@shell ~/sand]$ echo "$string1 $string2" | tr ' |' '\n'
abc
def
ghi
123:2
124:1
125:3
[ctsgnb@shell ~/sand]$ echo "$string1 $string2" | tr ' |' '\n' | pr -2 -t -s:
abc:123:2
def:124:1
ghi:125:3
[ctsgnb@shell ~/sand]$ echo "$string1 $string2" | tr ' |' '\n' | pr -2 -t -s: | sed 's/^\([^:]*\):\([^:]*\)/\2:\1/'
123:abc:2
124:def:1
125:ghi:3
[ctsgnb@shell ~/sand]$ echo "$string1 $string2" | tr ' |' '\n' | pr -2 -t -s: | sed 's/^\([^:]*\):\([^:]*\)/\2:\1/' | xargs
123:abc:2 124:def:1 125:ghi:3
[ctsgnb@shell ~/sand]$
sikku
July 5, 2011, 8:35am
13
I told you, it behaves in a different way.
$ echo "$string1 $string2"
abc|def|hij 123:2|124:1|125:3
$ echo "$string1 $string2" | tr ' |' '\n'
abc|def|hij
123:2|124:1|125:3
$ echo "$string1 $string2" | tr ' |' '\n' | pr -2 -t -s:
abc|def|hij:123:2|124:1|125:3
$ echo "$string1 $string2" | tr ' |' '\n' | pr -2 -t -s: | sed 's/^\([^:]*\):\([^:]*\)/\2:\1/' | xargs
123:abc|def|hij:2|124:1|125:3
---------- Post updated at 07:30 AM ---------- Previous update was at 07:26 AM ----------
Check this output:
$ echo "$string1 $string2" | tr '|' '\n'
abc
def
hij 123:2
124:1
125:3
---------- Post updated at 07:35 AM ---------- Previous update was at 07:30 AM ----------
Look at this now:
$ echo "$string1 $string2" | tr '|' '\n' | tr ' ' '\n'
abc
def
hij
123:2
124:1
125:3
lol.. I have no idea how its happening?
now the full command works:
$ echo "$string1 $string2" | tr '|' '\n' | tr ' ' '\n' | pr -2 -t -s: | sed 's/^\([^:]*\):\([^:]*\)/\2:\1/' | xargs
123:abc:2 124:def:1 125:hij:3
aigles
July 5, 2011, 8:52am
14
Merge the two tr
statement into one :
echo "$string1 $string2" | tr ' |' '\n\n'
Jean-Pierre.
1 Like
sikku
July 5, 2011, 10:19am
15
The latest one works in the command line but not in the script.
echo "$string1 $string2" | tr ' |' '\n\n' | pr -2 -t -s: | sed 's/^\([^:]*\):\([^:]*\)/\2:\1/' | xargs
the following one works in scripts, for now I am using this one itself.
paste -d: <((echo $string2 | sed 's/\|/ /g' | xargs -n1) | cut -f1 -d:) <(echo $string1 |
sed 's/\|/ /g' | xargs -n1) <((echo $string2 | sed 's/\|/ /g' | xargs -n1) | cut -f2 -d: ) | xargs
Is there any method to incorporate the first one into the script file?
---------- Post updated at 09:19 AM ---------- Previous update was at 08:43 AM ----------
I have new question:
I have a string:
s1="123:1,124:2,126:4"
I want
s2="123 124 126"
What should I use?
---
Got it:
$echo $s1 | tr ',' '\n' | cut -f1 -d: | xargs
123 124 126
Could you please explain the purpose of $ENV (in this context).
is ENV variable used to pull the environment variables (declared in the shell) into the script?
If that is the case ...the following didn't work...could you please correct it.
#!/bin/ksh
# this script is used to concatenate 2 strings after removing the delimiter
string1="abc|def|hij"; echo $string1;
string2="12|13|14"; echo $string2;
string3=$(perl -e '@f=split( /\|/, $string1);@s=split(/\|/, $string2);for (0..$#f){print "$f[$_]:$s[$_] "}')
echo $string3
thanks,
perl rookie
ctsgnb
July 6, 2011, 4:38am
17
@Sikku :
$echo $s1 | tr ',' '\n' | cut -f1 -d: | xargs
123 124 126
could be shorten (and save some pipe as well) with:
echo $s1 | sed 's/:[^,]*//g;s/,/ /g'
---------- Post updated at 10:38 AM ---------- Previous update was at 09:23 AM ----------
echo "$string1 $string2" | tr ' |' '\n\n' | pr -2 -t -s: | sed 's/^\([^:]*\):\([^:]*\)/\2:\1/' | xargs
Works in command line but does not work in your script ???
Could you please show the content of your script, it sounds weird that you could not pass that command from within your script .
1 Like
sikku
July 6, 2011, 5:32am
18
@ctsgnb :
This is the content of my script
#!/bin/ksh
string1="abc|def|hij"
string2="123:1|134:2|145:3"
#string3="`paste -d: <((echo $string2 | sed 's/\|/ /g' | xargs -n1) | cut -f1 -d:) <(echo $string1 | \
# sed 's/\|/ /g' | xargs -n1) <((echo $string2 | sed 's/\|/ /g' | xargs -n1) | cut -f2 -d: ) | xargs`"
string3="`echo "$string1 $string2" | tr ' |' '\n\n' | pr -2 -t -s: | sed 's/^\([^:]*\):\([^:]*\)/\2:\1/' | xargs`"
echo $string3
I get this error: (list is the script name)
$ list
./list[9]: : cannot execute
./list[9]: 123:1|134:2|145:3 | tr ' |' '\n\n' | pr -2 -t -s: | sed 's/^\([^:]*\):\([^:]*\)/\2:\1/' | xargs: cannot execute
ctsgnb
July 6, 2011, 5:35am
19
Try this :
string3=$(echo "$string1 $string2" | tr ' |' '\n\n' | pr -2 -t -s: | sed 's/^\([^:]*\):\([^:]*\)/\2:\1/' | xargs )
echo $string3
1 Like
sikku
July 6, 2011, 5:46am
20
In fact my script should be like this:
#!/bin/ksh
string1="abc|def|hij"
string2="1212|2134|1245"
string3="123:1|134:2|145:3"
string4="`paste -d: <(echo $string1 | sed 's/\|/ /g' | xargs -n1) <(echo $string2 | sed 's/\|/ /g' | xargs -n1) | xargs`"
#string4="$string3 `paste -d: <((echo $string3 | sed 's/\|/ /g' | xargs -n1) | cut -f1 -d:) <(echo $string1 | \
# sed 's/\|/ /g' | xargs -n1) <((echo $string2 | sed 's/\|/ /g' | xargs -n1) | cut -f2 -d: ) | xargs`"
string4="$string4 `echo "$string1 $string3" | tr ' |' '\n\n' | pr -2 -t -s: | sed 's/^\([^:]*\):\([^:]*\)/\2:\1/' | xargs`"
echo $string3
I want to add string3 to string4 and then append the last result to string4 again.
---------- Post updated at 04:46 AM ---------- Previous update was at 04:43 AM ----------
Ok. Its working now. Thanks.
Edited: string3 to string4