sed: -e expression #1, char 0: no previous regular expression

Hello All,

I'm trying to extract the lines between two consecutive elements of an array from a file.
My array looks like:

problem_arr=(PRS111 PRS213 PRS234)

j=0
while [ $j -le ${problem_arr[@]} ]
do
    k=`expr $j + 1`
    sed  -n "/${problem_arr[$j]}/,/${problem_arr[$k]}/p" problemid.txt
    ---some operation goes here----
    j=`expr $j + 1`
done

However, i get

sed: -e expression #1, char 0: no previous regular expression

error message.

Just to help you narrow down the problem i want to convey u that following line works:

sed  -n "/${problem_arr[0]}/,/${problem_arr[1]}/p" problemid.txt

Could you please help me how to use array subscript variable in such cases? Thank you so much in advance!

Regards,
Indu

Looks like you've got two problems in your script - obviously both with the line while [ $j -le ${problem_arr[@]} ]
First: ${problem_arr[@]} will yield ALL array members and the shell should complain when trying to compare. I guess you want it to read ${#problem_arr[@]} which yields the count of members in array.
Second: You correctly start the loop at j=0 , but you run it one too far up - ${problem_arr[${#problem_arr[@]}]} will be empty and thus sed complains. make the comparison [ $j -lt ... ] and it will fly.

Thanks RudiC for your response.
I verified the points you have highlighted, and there is no problem with array size & initialization.Anyways, i can assign array size to another variable and use it in while condition.
I'd want you just focus on sed part of it, as it throws error there.

Hope you got me right!

Regards,
Indu

That sed error means that the first use of a regular expression is empty. That's happenning because your variable expansion yields nothing.

If you modified your script according to RudiC's suggestions, post it so we can see the current version.

Also, you may find it instructive to insert set -x before the while-loop.

Regards,
Alister

You haven't said what shell you're using, but at least with bash and ksh, setting an array with:

array=(a b c)

sets ${array[1]} to a, ${array[2]} to b, and ${array[3]} to c. It doesn't set ${array[0]} so your first call to sed

sed  -n "/${problem_arr[0]}/,/${problem_arr[1]}/p" problemid.txt

expands to:

sed  -n "//,/PRS111/p" problemid.txt

and since your first RE is //, it is trying to search for the previously used RE (but there is no previously used RE in this invocation of sed.

Sorry, disagree. From the bash man page:

Running InduInduIndu's code snippet - using ${#...} to correctly get the member count - fails in the fourth loop,

++ k=4
++ sed -n //,//p problemid.txt
sed: -e expression #1, char 0: no previous regular expression

indicating that he should limit his loop count to 0 - 2. The first loop works fine:

++ sed -n /PRS111/,/PRS213/p problemid.txt

Ouch. Yes, you're right. Both bash and ksh use the same notation for setting an indexed array, but bash uses 0 based indexing and ksh uses 1 based indexing. (I guess you can tell that I do most of my shell scripting with ksh. :rolleyes:)

Hello RodiC & Alister,
Im using bash. My code is now running fine with no error.

  1. I first tried to assign the elements manually like:
i=1
while [ $i -lt ${#arr$} ]
do
arr[$i]=element(comes from a file )
i=`expr $i + 1`
done
j=`expr $i + 1`
 
sed -n "/${arr[$i]}/,/${arr[$j]}/p" <file>
<--some operation ....>

The above works.

  1. Also, limiting size to 1 down and counting from 0 works.

Thanks both of you for hitting the nail.Appreciate it!

Regards,
Indu

Does it? I'm not sure I understand what you are doing there. In the while loop, you say you are populating array arr from a file. How do you know when to terminate the loop, and what do you expect from the ${#arr$} construct? And how do you assign an element from a file to member arr[$i]?

Are you starting from 0? i=1

Hi Rodic,
This is the excat thing i was doing:

problem_arr=`grep -E -o "PRB[0-9]{1,4}" problemid.txt`
j=1
while [ $j -le ${problem_arr[@]} ]
do
    k=`expr $j + 1`
    sed  -n "/${problem_arr[$j]}/,/${problem_arr[$k]}/p" problemid.txt >xyz.txt
    < so many operation here like between two problems there will be so many states like New, Inprogress, Resolved, closed & date. I have to do opeartions to calculate the time spent in each state for each problem...>
    j=`expr $j + 1`
done

Thanks,
Indu

You say (post #8) that you are using bash. Array indexing in bash starts from 0 and counts up to ${#arr[@]} - 1 , as stated earlier. In both your posts #8 and #10, you are starting the while loop for array indexing at 1 (i=1 or j=1). So you will be missing the first element in your problem_arr! And in either post you are NOT using the correct method to evaluate the number of elements in the array, which I duplicated above. Btw, the way you assign your problem_arr will not work, as it does not result in an array but in a single variable with n space separated words.

1 Like

Really Sorry RodiC i couldn't exactly copy pasted my script here coz the script lies in the system where this site is blocked. I'd need to make hell lot of effort to exactly copy paste code. So i just tried to simulate the problem here above.
Yes, You are right! so many things which i abstracted here considering those are kind of implicit.

 
IFS=$'\n'
problem_arr=$(`grep -E -o "PRB[0-9]{1,4}" problemid.txt`)
unset IFS

And i haven't missed any element if i have assigned elements from index 1 to size of array. However, if i had used indexing from 0, i would have limit loop to size-1.

Anyways, appreciate your effort to come forward for understing the real problem. You are simply awesome!!

Thanks,
Indu