Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sed: replace multiple periods with another character

Tags:

sed

I'm making a table in emacs org-mode of sunrise-commander commands from the .el file (want to make a cheat sheet). The list looks like this:

/, j .......... go to directory
p, n .......... move cursor up/down
M-p, M-n ...... move cursor up/down in passive pane
^, J .......... go to parent directory
...

I want to make that into an org-mode table with this format:

| /, j     | go to directory                     |
| p, n     | move cursor up/down                 |
| M-p, M-n | move cursor up/down in passive pane |
| ^, J     | go to parent directory              |
...

Org will take care of spacing; I just need "| command | explanation |"

I can't get sed to replace multiple periods with a vertical slash. My current attempts have been like this:

cat in.org | sed -e 's/[.]*/|/g' > out.org
cat in.org | sed -e 's/[.]/|/g' > out.org
cat in.org | sed -e 's/[.*]/|/g' > out.org

I've already used this to replace leading and trailing whitespace with vertical slashes:

sed -e 's/^[ \t]*/|/g;s/[ \t]*$/|/g'|

Now I just need to do the same for a string of periods. I'm afraid I don't understand sed well enough to get it to treat periods like a period (and target a blob of them) rather than treating them as wildcards. The second and third treat each period like a period, as I end up with a bunch of vertical slashes.

But the first just seem to put a vert slash between every single character so I'm not sure why it's doing that. It seems like it's going back to acting like the wildcard character.

Thanks for any help.

like image 448
Hendy Avatar asked Nov 12 '10 20:11

Hendy


People also ask

Does sed support multiline replacement?

By default, when sed reads a line in the pattern space, it discards the terminating newline (\n) character. Nevertheless, we can handle multi-line strings by doing nested reads for every newline.

How do you sed multiple times?

You can tell sed to carry out multiple operations by just repeating -e (or -f if your script is in a file). sed -i -e 's/a/b/g' -e 's/b/d/g' file makes both changes in the single file named file , in-place.

How do you use sed for substitution?

Find and replace text within a file using sed command Use Stream EDitor (sed) as follows: sed -i 's/old-text/new-text/g' input.txt. The s is the substitute command of sed for find and replace. It tells sed to find all occurrences of 'old-text' and replace with 'new-text' in a file named input.txt.


2 Answers

You need to escape the period; period matches "any character". Further, since sed doesn't always have a + (1 or more) operator, you need to explicitly specify one followed by 0 or more, as in:

sauer@trogdor:~$ echo 'h...ello world' | sed 's/^/|/;s/\.\.*/|/;s/$/|/'
|h|ello world|

And, after rereading your question, you want a pipe at the beginning and end. So, replace ^ and $ with a pipe as well. You can do that with three -e expressions, but I like just putting all three in the command line separated by semicolons. It helps make the pattern look more like line noise. :)

If you want to match, say, 2 or more periods, use \.\.\.*. Etc. It's a shame that sed doesn't consistently support range expressions.

like image 137
dannysauer Avatar answered Nov 22 '22 13:11

dannysauer


This should do it for you:

sed -r -e 's/\.{2,}/|/' -e 's/(.*)/|\1|/'

The {2,} just says to match 2 or more, so that if you run into periods in other places, you wont have an issue. The '-e' proceeds multiple regexes, and the '-r' means use extended regexes.

Hope it works, it does on gnu sed 4.1.2.

like image 44
Seamus Connor Avatar answered Nov 22 '22 14:11

Seamus Connor