Hi.
I have an interesting problem and i couldn't find out the solution.
I have two variables in which there are a lot of lines finished by \n. I would like to concatenate this two variables into one in this format:
var1[1st line]var2[1st line]
var1[2nd line]var2[2nd line]
.
.
.
I could do this simply by command paste but it works only with two files. The problem is that I cannot create any temporary files. I can use only variables. I searched everywhere and tried everything but without succes.
Hope sbdy find a solution.
Thanks a lot.
Some shells support process substitution which is what you need in this case. Could you explain why you cannot use temporary files?
I cannot use them. In my case it is forbidden to use them so I need to avoid it and make the solution fast enough (eg it should work for 4000 lines in a minute)
Can you post sample of the input.
16298 mmap2(NULL, 83186, PROT_READ, MAP_PRIVATE, 3, 0 <unfinished ...>
16299 <... brk resumed> ) = 0x8051000
16298 <... mmap2 resumed> ) = 0xb7f71000
16298 close(3 <unfinished ...>
16299 access("/etc/ld.so.nohwcap", F_OK <unfinished ...>
16298 <... close resumed> ) = 0
16299 <... access resumed> ) = -1 ENOENT (No such file or directory)
Post sample of output also there's no way I can figure out what the result should be.
16298 mmap2(NULL, 83186, PROT_READ, MAP_PRIVATE, 3, 0 <unfinished ...> 16298 <... mmap2 resumed> ) = 0xb7f71000 \n
16298 close(3 <unfinished ...>16298 <... close resumed> ) = 0 \n
16299 access("/etc/ld.so.nohwcap", F_OK <unfinished ...> 16299 <... access resumed> ) = -1 ENOENT (No such file or directory) \n
Try this script or change it however you want. It uses the coprocess feature of the shell...
#!/usr/bin/sh
var1="var1line1\n
var1line2\n
var1line3\n
var1line4"
var2="var2line1\n
var2line2\n
var2line3"
echo $var1 |&
exec 3>&p; exec 4<&p
echo $var2 |&
exec 5>&p; exec 6<&p
while true
do
read -u4 v1
read -u6 v2
if [ -z "$v1" -a -z "$v2" ]; then
break
else
if [ -z "$v1" ]; then
echo "$v2"
elif [ -z "$v2" ]; then
echo "$v1"
else
echo "$v1 $v2"
fi
fi
done
Maybe what I'm asking seems a bit trivial, which of the following is the format of your data?
VARIABLE="line1
line2
line3
...
or
VARIABLE="line1\n
line2\n
line3\n
...
What I mean is that do you explicitly write at the end of each line \n or you just push the enter key in order to insert a new line?
No I think that is a very good point...I had the same doubt and wanted to ask the OP about it but you beat me to it.
As dariyoosh brought up a very valid point so I changed the script...
#!/usr/bin/sh
var1="var1line1
var1line2
var1line3
var1line4"
var2="var2line1
var2line2
var2line3"
echo "$var1" |&
exec 3>&p; exec 4<&p
echo "$var2" |&
exec 5>&p; exec 6<&p
while true
do
read -u4 v1
read -u6 v2
if [ -z "$v1" -a -z "$v2" ]; then
break
else
if [ -z "$v1" ]; then
echo "$v2"
elif [ -z "$v2" ]; then
echo "$v1"
else
echo "$v1 $v2"
fi
fi
done
Assuming that you don't explicitly write \n at the end of each line, I think the following KornShell script does the job.
#!/bin/ksh
# The fact that we set IFS only on new line is that in this question
# space and tabs are not considered as delimiters, only new lines
IFS='
'
FINAL_RESULT=""
RESULT=""
function concatenate
{
VARIABLE1=$1
VARIABLE2=$2
CURRENT_LINE_NUMBER_IN_VARIABLE1=1
CURRENT_LINE_NUMBER_IN_VARIABLE2=1
for ITERATOR1 in $VARIABLE2
do
CURRENT_LINE_NUMBER_IN_VARIABLE1=1
for ITERATOR2 in $VARIABLE1
do
if (( CURRENT_LINE_NUMBER_IN_VARIABLE1 <
CURRENT_LINE_NUMBER_IN_VARIABLE2 ))
then
(( CURRENT_LINE_NUMBER_IN_VARIABLE1 =
CURRENT_LINE_NUMBER_IN_VARIABLE1 + 1 ))
elif (( CURRENT_LINE_NUMBER_IN_VARIABLE1 ==
CURRENT_LINE_NUMBER_IN_VARIABLE2 ))
then
FINAL_RESULT="$FINAL_RESULT\n$ITERATOR2$ITERATOR1"
(( CURRENT_LINE_NUMBER_IN_VARIABLE1 =
CURRENT_LINE_NUMBER_IN_VARIABLE1 + 1 ))
break;
else
break 2;
fi
done
(( CURRENT_LINE_NUMBER_IN_VARIABLE2 =
CURRENT_LINE_NUMBER_IN_VARIABLE2 + 1 ))
done
CURRENT_LINE=1
for ITERATOR1 in $VARIABLE1
do
# The following condition ignores the lines in VARIABLE1
# that were read in the precedent loop
if (( CURRENT_LINE < CURRENT_LINE_NUMBER_IN_VARIABLE1 ))
then
(( CURRENT_LINE = CURRENT_LINE + 1 ))
# Here we concatenate the rest of the lines in VARIABLE1 with
# the final result.
else
FINAL_RESULT="$FINAL_RESULT\n$ITERATOR1"
(( CURRENT_LINE = CURRENT_LINE + 1 ))
(( CURRENT_LINE_NUMBER_IN_VARIABLE1 =
CURRENT_LINE_NUMBER_IN_VARIABLE1 + 1 ))
fi
done
(( TOTAL_LENGTH_MINUS_FIRST_NEW_LINE = ${#FINAL_RESULT} - 2 ))
FINAL_RESULT=${FINAL_RESULT:2:$TOTAL_LENGTH_MINUS_FIRST_NEW_LINE}
}
# In this example we suppose VARIABLE1 and VARIABLE2 are those lines
# that have to be concatenated, each line by its corresponding in
# another variable
VARIABLE1="var1 first line
var1 second line
var1 third line
var1 forth line
var1 fifth line
var1 sixth line
var1 seventh line"
VARIABLE2="var2 first line
var2 second line
var2 third line
var2 forth line
var2 fifth line"
# As you didn't specify in your problem whether both variables have
# the same number of lines, I considered also the case in which the
# number of lines in each variable is different
NUMBER_OF_NEW_LINES_IN_VARIABLE1=0
NUMBER_OF_NEW_LINES_IN_VARIABLE2=0
for ITERATOR in $VARIABLE1
do
(( NUMBER_OF_NEW_LINES_IN_VARIABLE1 =
NUMBER_OF_NEW_LINES_IN_VARIABLE1 + 1 ))
done
for ITERATOR in $VARIABLE2
do
(( NUMBER_OF_NEW_LINES_IN_VARIABLE2 =
NUMBER_OF_NEW_LINES_IN_VARIABLE2 + 1 ))
done
if (( $NUMBER_OF_NEW_LINES_IN_VARIABLE1 >=
$NUMBER_OF_NEW_LINES_IN_VARIABLE2 ))
then
concatenate "$VARIABLE1" "$VARIABLE2"
else
concatenate "$VARIABLE2" "$VARIABLE1"
fi
print $FINAL_RESULT
yes both files have the sime number of lines. and \n is not written in variables...
to the script from shamrock an error occured:
line12: syntax error near unexpected token`&'
line12: `echo $var1|&'
Well in this case, try this
#!/bin/ksh
# The fact that we set IFS only on new line is that in this question
# space and tabs are not considered as delimiters, only new lines
IFS='
'
FINAL_RESULT=""
RESULT=""
function concatenate
{
VARIABLE1=$1
VARIABLE2=$2
CURRENT_LINE_NUMBER_IN_VARIABLE1=1
CURRENT_LINE_NUMBER_IN_VARIABLE2=1
for ITERATOR1 in $VARIABLE1
do
CURRENT_LINE_NUMBER_IN_VARIABLE2=1
for ITERATOR2 in $VARIABLE2
do
if (( CURRENT_LINE_NUMBER_IN_VARIABLE2 <
CURRENT_LINE_NUMBER_IN_VARIABLE1 ))
then
(( CURRENT_LINE_NUMBER_IN_VARIABLE2 =
CURRENT_LINE_NUMBER_IN_VARIABLE2 + 1 ))
else
FINAL_RESULT="$FINAL_RESULT\n$ITERATOR1$ITERATOR2"
(( CURRENT_LINE_NUMBER_IN_VARIABLE2 =
CURRENT_LINE_NUMBER_IN_VARIABLE2 + 1 ))
break;
fi
done
(( CURRENT_LINE_NUMBER_IN_VARIABLE1 =
CURRENT_LINE_NUMBER_IN_VARIABLE1 + 1 ))
done
(( TOTAL_LENGTH_MINUS_FIRST_NEW_LINE = ${#FINAL_RESULT} - 2 ))
FINAL_RESULT=${FINAL_RESULT:2:$TOTAL_LENGTH_MINUS_FIRST_NEW_LINE}
}
# In this example we suppose VARIABLE1 and VARIABLE2 are those lines
# that have to be concatenated, each line by its corresponding in
# another variable
VARIABLE1="var1 first line
var1 second line
var1 third line
var1 forth line
var1 fifth line"
VARIABLE2="var2 first line
var2 second line
var2 third line
var2 forth line
var2 fifth line"
concatenate "$VARIABLE1" "$VARIABLE2"
print $FINAL_RESULT
Switch to the ksh and replace the very first line with #!/usr/bin/ksh
it is the same error
Did you run my script to see the result?
yes i do but i for input 2400 lines it worked really really long.....