0

I have to remove .. character from a file in Bash script. Example:

I have some string like:

some/../path/to/file
some/ab/path/to/file

And after replace, it should look like

some/path/to/file
some/ab/path/to/file

I have used below code

DUMMY_STRING=/../
TEMP_FILE=./temp.txt
sed s%${DUMMY_STRING}%/%g ${SRC_FILE} > ${TEMP_FILE}
cp ${TEMP_FILE} ${SRC_FILE}

It is replacing the /../ in line 1; but it is also removing the line /ab/ from second line. This is not desired. I understand it is considering /../ as some regex and /ab/ matches this regex. But I want only those /../ to be replaced.

Please provide some help.

Thanks,

NN

0

1 Answer 1

3

The . is a metacharacter in sed meaning 'any character'. To suppress its special meaning, escape it with a backslash:

sed -e 's%/\.\./%/%g' $src_file > $temp_file

Note that you are referring to different files after you eliminate the /../ like that. To refer to the same name as before (in the absence of symlinks, which complicate things), you would need to remove the directory component before the /../. Thus:

some/../path/to/file
path/to/file

refer to the same file, assuming some is a directory and not a symlink somewhere else, but in general, some/path/to/file is a different file (though symlinks could be used to confound that assertion).


$ x="some/../path/to/file
> some/ab/path/to/file
> /some/path/../to/another/../file"
$ echo "$x"
some/../path/to/file
some/ab/path/to/file
/some/path/../to/another/../file
$ echo "$x" | sed -e 's%/\.\./%/%g'
some/path/to/file
some/ab/path/to/file
/some/path/to/another/file
$ echo "$x" | sed -e "s%/\.\./%/%g"
some/path/to/file
some/ab/path/to/file
/some/path/to/another/file
$ echo "$x" | sed -e s%/\.\./%/%g
some/path/file
some/path/file
/some/path/to/another/file
$ echo "$x" | sed -e s%/\\.\\./%/%g
some/path/to/file
some/ab/path/to/file
/some/path/to/another/file
$

Note the careful use of double quotes around the variable "$x" in the echo commands. I could have used either single or double quotes in the assignment and would have gotten the same result.

Test on Mac OS X 10.7.4 with the standard sed (and shell is /bin/sh, aka bash 3.2.x), but the results would be the same on any system.

Sign up to request clarification or add additional context in comments.

3 Comments

This is not working as desired. It is also removing "/tx/" which I do not want. I want only that sequence "/../" should be replaced by "/".
@Niranjan: Are you using single quotes or double quotes around the sed script? They are not interchangeable — at least, not in this context. Or are you still not using any quotes? If you do not use single quotes, you have to use more backslashes. As a rule of thumb, enclose sed scripts in single quotes unless you need to interpolate a shell variable.
Got the point Jonathan. I was not using any quote in SED command at all. Your suggestion was proposing to use single quote. That single quote sed -e 's%/\.\./%/%g' ${SRC_FILE} > ${TEMP_FILE} solved the problem. Appreciate your help. Thank you very much.

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.