0

I’m having some issues trying to edit a file with SED using a variable that has forward slashes in it.

The file I’m trying to edit “checksum” has the following contents…

758f9775093bf885dbc963cba1aec732,/bin/bash
1b45027142521f2a1c3d95891770eb47,/etc/grub.conf
2a34dc288f7994cc7b1b338605ef8775,/etc/hosts
03f670845fe199955f9a0babecbda9a0,/etc/networks

I want to search for the string “/bin/bash” using a variable (file_path=“/bin/bash”) and when I find that string, remove everything up to the “,” and replace with the work “VALID”.

Here’s my sed syntax and attempts below, however it fails when I try to use the variable. Any suggestions?

Success without variable

# sed '\/bin\/bash/ s/^.*,/VALID,/g' checksum
VALID,/bin/bash
1b45027142521f2a1c3d95891770eb47,/etc/grub.conf
2a34dc288f7994cc7b1b338605ef8775,/etc/hosts
03f670845fe199955f9a0babecbda9a0,/etc/networks

Failure with variable

# file_path="/bin/bash"
# echo $file_path
/bin/bash

# sed '/$file_path/ s/^.*,/VALID,/g' checksum
758f9775093bf885dbc963cba1aec732,/bin/bash
1b45027142521f2a1c3d95891770eb47,/etc/grub.conf
2a34dc288f7994cc7b1b338605ef8775,/etc/hosts
03f670845fe199955f9a0babecbda9a0,/etc/networks

I’ve tried wrapping the variable in quotes, {} and still had the same failures:

# sed '/"$file_path"/ s/^.*,/VALID,/g' checksum
758f9775093bf885dbc963cba1aec732,/bin/bash
1b45027142521f2a1c3d95891770eb47,/etc/grub.conf
2a34dc288f7994cc7b1b338605ef8775,/etc/hosts
03f670845fe199955f9a0babecbda9a0,/etc/networks

# sed '/{$file_path}/ s/^.*,/VALID,/g' checksum
758f9775093bf885dbc963cba1aec732,/bin/bash
1b45027142521f2a1c3d95891770eb47,/etc/grub.conf
2a34dc288f7994cc7b1b338605ef8775,/etc/hosts
03f670845fe199955f9a0babecbda9a0,/etc/networks

I’ve also used “|” as the escape character.

# sed '|{$file_path}| s|^.*,|VALID,|g' checksum
sed: -e expression #1, char 1: unknown command: `|'

Any suggestions on how to accomplish this?

# sed --version
GNU sed version 4.2.1

3 Answers 3

1

The single quotes inhibit variable substitution. Try this:

sed "\:$file_path: s/^.*,/VALID,/" checksum

Note that I've changed the pattern delimiter to a colon so that the slashes in the variable's value won't end the pattern.

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

1 Comment

Perfect! I will use this. I see another area I was wrong when testing with different delimiters. I was not escaping them. Thanks for your help.
1

To complete @ooga's good answer. It can be interesting to keep single quotes to avoid ambiguities that may occur with special characters that bash can interpret. To do that, you can simply close the sed block with a single quote to reopen it later:

sed '\~'$file_path'~s~^[^,]*~VALID~' checksum

5 Comments

With oogas answer $file_path was within double quotes but with yours it's not within any quotes. How is that better?
It isn't better or worse, it's the way to do it with single quotes. The main interest is that you can write whatever you want between single quotes without bash interprets it.
@CasimiretHippolyte I beg to differ here. Not quoting a variable at the cost of avoiding bash to interpret a non-existent interpolating element is actually worse. :P
@CasimiretHippolyte your variable isn't between single quotes though, it's outside of any quotes. If you want the REST of the script in single instead of double quotes then you could write it as sed '\~'"$file_path"'~s~^[^,]*~VALID~' checksum but I don't see the benefit of the added complexity for this script.
+1 @CasimiretHippolyte, I had to put my sed command in a bash script and using your syntax the variable was interpreted correctly. I'm glad you offered your take on this problem.
1

Just use awk for a simple life:

awk -v fp="$file_path" 'BEGIN{FS=OFS=","} $2==fp{$1="Valid"} 1' file

That will work no matter what the contents of file_path, including / or an RE metacharacters or shell globbing characters and it won't produce a false match if it's contents partially match any part of line in the file.

1 Comment

Thank you this does work and I always to make my life easier. I should start using more awk, but tend to gravitate to sed since that's what I know more.

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.