1

I want to do (in bash script):

NEWBASE=`echo $NAME | sed "s/${DIR}//g" | sed 's/.\///g'`

I read in the net, that I have to replace single quote with double quote.
This is unfortunately not working. Why?
Thanks

3
  • 2
    Post an input along with expected output. Commented Sep 16, 2015 at 16:01
  • you are missing the final execution single quote... ` Commented Sep 16, 2015 at 16:02
  • the final execution single quote is there, sorry Commented Sep 16, 2015 at 16:05

2 Answers 2

1

sed is overkill for this. Use parameter expansion:

NEWBASE=${NAME//$DIR//}
NEWBASE=${NEWBASE//.\//}
Sign up to request clarification or add additional context in comments.

5 Comments

Sorry I don't understand your point?? I have to perform some string manipulations with sed.
I haven't posted all the sed executions. There is more than the 2 above
It's not what I expected but it's working! Thank you chepner
When possible, you want to use built-in shell commands rather than starting an external program. sed is appropriate if you have a file full of lines, all of which are processed identically, but when you are only echoing a single string, you can often use the shell itself to process it.
As a matter of fact I have multiple subdirectories full of images. I have to perform many tasks on this images like resizing, compressing and at the end rename them using directory names.
0

It is important to understand that bash and sed are two completely independent things. When you give bash a command, it first processes it according to its rules, in order to come up with a utility name and a set of arguments for that utility (in this case sed), and then calls the utility with the arguments.

Probably $DIR contains a slash character. Perhaps it looks something like /usr/home/codyline/src.

So when bash substitutes that into the argument to the sed command:

"s/${DIR}//g"

the result is

s//usr/home/codyline/src//g

which is what is then passed to sed. But sed can't understand that commabnd: it has (many) too many / characters.

If you really want to use sed for this purpose, you need to use a delimiter other than /, and it needs to be a character you are confident will never appear in $DIR. Fortunately, the sed s command allows you to use any character as a delimiter: whatever character follows the s is used as the delimiter. But there always must be exactly three of them in the command.

For example, you might believe that no directory path contains a colon (:), in which case you could use:

sed "s:${DIR}::g"

Of course, someday that will fail precisely because you have a directory with a colon in its name. So you could make things more general by using bash's substitute-and-replace feature to backslash-escape all the colons:

sed "s:${DIR//:/\:}::g"

But you could have used this bash feature in order to avoid the use of sed altogether:

NEWBASE=${NAME//$DIR}

Unfortunately, you can't nest bash substitute-and-replaces, so you need to do them sequentially:

NEWBASE=${NEWBASE//.\/}

Note: I used ${var//...}, which is the equivalent of specifying the g flag in a sed s command, but I really don't know if it is appropriate. Do you really expect multiple instances of $DIR in a single path? If there are multiple instances, do you really want to remove all of them? You'll have to decide.

1 Comment

Thanks rici. I solved my problem like suggested by @chepner: NEWBASE=${NAME//$DIR//} NEWBASE=${NEWBASE//.\//} and than executing sed tasks. It's not a one liner any more but it works.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.