1

I want to replace a string in a text file with a sequence of numbers such as 1 2 3 4 5 6 7 preferably using sed.

Here is what I have tried (without the search string) and seems to work:

for i in {1..5};do echo $(seq 1 $i); done

The output:

1
1 2
1 2 3
1 2 3 4
1 2 3 4 5

However, when I try this:

for i in {1..5};do sed -i "s/abc/$(seq 1 $i)/g" test; done

I get the following error:

sed: -e expression #1, char 8: unterminated `s' command
sed: -e expression #1, char 8: unterminated `s' command
sed: -e expression #1, char 8: unterminated `s' command
sed: -e expression #1, char 8: unterminated `s' command

I have tried enclosing the replacement string in brackets as well, but it does not seem to work.

The first loop

for i in {1..5}

will be replaced by a glob for filenames within which I want to replace some parameters.

  • 1
    can u share the content of text file... – msp9011 Jul 15 at 19:07
  • The test text file I am using is just the letters abc. – smog Jul 15 at 20:59
0

TL; DR:

There can be some ways to work around that, I think the cleanest for your sample case is:

for i in {1..5};do sed -i "s/abc/$(seq -s ' ' 1 $i)/g" test; done

That is: we request seq to use one single space to separate each number.

Explanation:

The reason why you got those errors is because the output from:

seq 1 5

is not:

1 2 3 4 5

but rather:

1
2
3
4
5

And since you enclosed the $(seq 1 $i) Command Substitution within double-quotes, the usual Word Splitting is not performed, hence all the newlines (except the last) output by the seq utility are left as is.

Therefore the actual sed command has become:

sed -i "s/abc/1
2
3
4
5
/g" test

which is not accepted because, as far as sed is concerned, you provided it with a s/abc/1 command, i.e. lacking the required final /.

An echo $(seq 1 5) does print 1 2 3 4 5 because the $(seq 1 5) is not within double-quotes, therefore Word Splitting occurs as per shell's default behavior.

We might indeed fix your sample case also as in:

for i in {1..5};do sed -i "s/abc/$(echo $(seq 1 $i))/g" test; done

that is, by doing a Command Substitution (your original seq 1 $i) inside another Command Substitution (the echo one).

This works even within the double-quotes because the $(echo ...) Command Substitution is run in a subshell which is not in the "I-am-inside-a-double-quote" state, so Word Splitting on the output from seq will be performed there.

  • Instead of echo $(seq 1 $i) you could use seq -s' ' 1 $i. – Freddy Jul 15 at 21:20
  • This worked perfectly. Thanks for the detailed explanation! – smog Jul 15 at 21:20
0

You can pipe the output to a temporary file, then move the temporary file over the original one. Also, you may have meant to operate on one line at a time, in which case you should drop the g:

for i in {1..5}; do
    sed -e "s/abc/$(seq 1 $i)/" test > test.tmp
    mv test.tmp test
done
  • This expression also gives the same error. I think the problem here is that bash is probably unable to print the entire sequence out at once. It's confusing because the format works with echo command but not with sed. – smog Jul 15 at 21:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.