Rønny Schmatzler
Rønny Schmatzler

Reputation: 77

Replace string between square brackets with sed

I have some strings in a textfile that look like this:

[img:3gso40ßf]

I want to replace them to look like normal BBCode:

[img]

How can I do that with sed? I tried this one but it doesn't do anything:

sed -i 's/^[img:.*]/[img]/g' file.txt

Upvotes: 3

Views: 13704

Answers (1)

jub0bs
jub0bs

Reputation: 66422

Escape those square brackets

Square brackets are metacharacters: they have a special meaning in POSIX regular expressions. If you mean [ and ] literally, you need to escape those characters in your regexp:

$ sed -i .bak 's/\[img:.*\]/\[img\]/g' file.txt

Use [^]]* instead of .*

Because * is greedy, .* will capture more than what you want; see Jidder's comment. To fix this, use [^]]*, which captures a sequence of characters up to (but excluding) the first ] encountered.

$ sed -i .bak 's/\[img:.[^]]\]/\[img\]/g' file.txt

Are you using an incorrect sed -i syntax?

(Thanks to j.a. for his comment.)

Depending on the flavour of sed that you're using, you may be allowed to use sed -i without specifying any <extension> argument, as in

$ sed -i 's/foo/bar/' file.txt

However, in other versions of sed, such as the one that ships with Mac OS X, sed -i expects a mandatory <extension> argument, as in

$ sed -i .bak 's/foo/bar/' file.txt

If you omit that extension argument (.bak, here), you'll get a syntax error. You should check out your sed's man page to figure out whether that argument is optional or mandatory.

Match a specific number of characters

Is there a way to tell sed that there are always 8 random characters after the colon?

Yes, there is. If the number of characters between the colon and the closing square bracket is always the same (8, here), you can make your command more specific:

$ sed -i .bak 's/\[img:[^]]\{8\}\]/\[img\]/g' file.txt

Example

# create some content in file.txt
$ printf "[img:3gso40ßf]\nfoo [img:4t5457th]\n" > file.txt

# inspect the file
$ cat file.txt
[img:3gso40ßf]
foo [img:4t5457th]

# carry out the substitutions
$ sed -i .bak 's/\[img:[^]]\{8\}\]/\[img\]/g' file.txt

# inspect the file again and make sure everything went smoothly
$ cat file.txt
[img]
foo [img]

# if you're happy, delete the backup that sed created
$ rm file.txt.bak

Upvotes: 11

Related Questions