2

I have already seen other answers trying to solve my problem but I am not able to solve it.

#!/bin/bash
s=org.gnome.Terminal.Legacy.Keybindings
g=$(echo $s | sed "s|\.|/|g") 
echo $g

I have above script which returns

org/gnome/Terminal/Legacy/Keybindings

but I need to append / at the end of this so that it becomes

org/gnome/Terminal/Legacy/Keybindings/

How to extend my sed script for this?

4

sed approach:

s="org.gnome.Terminal.Legacy.Keybindings"
g=$(echo $s | sed "y|.|/|; s|$|/|")
echo $g
org/gnome/Terminal/Legacy/Keybindings/

  • y|\.|/| - translate all dots . to slashes /
  • what is the difference between s|ToBeReplaced|ReplaceByThis and y|ToBeReplaced|ReplaceByThis in sed – GypsyCosmonaut Jul 3 '17 at 21:22
  • 2
    @GypsyCosmonaut, 1) y/src/dst/ - Transliterate any characters in the pattern space which match any of the source-chars with the corresponding character in dest-chars. 2) s/regexp/replacement/flags - the s command attempts to match the pattern space against the supplied regular expression regexp; if the match is successful, then that portion of the pattern space which was matched is replaced with replacement. – RomanPerekhrest Jul 3 '17 at 21:25
  • thank you Roman, do you have any suggestions for any books where I can learn sed from? – GypsyCosmonaut Jul 3 '17 at 21:30
  • 3
    You don't need to escape . for the y command, it accepts literal characters. y|.|/|. The y commands transliterates, matching single characters from src and replacing them with characters from dst. E.g. y,abcdefghijklmnoprstuvwxyz,ABCDEFGHIJKLMNOPRSTUVWXYZ, would change all text to upper-case. – Gene Pavlovsky Jul 3 '17 at 21:31
  • @GenePavlovsky, that was easy – RomanPerekhrest Jul 4 '17 at 6:08
8

You don't really need sed for this, if you're using bash.

s="org.gnome.Terminal.Legacy.Keybindings"
g=${s//.//}/

Read the Parameter Expansion section of bash man page (${parameter/pattern/string}), it also has many other useful things.

With sed, you can also specify multiple expressions, sometimes it is more readable.

s="org.gnome.Terminal.Legacy.Keybindings"
g=$(sed -e 'y,.,/,' -e 's,$,/,' <<<$s)

Note that with y command you don't have to escape the ., y command accepts literal characters.

6

Try this:

sed 's/\.\|$/\//g'
  • | is the alternation operator.
  • $ will match the end of line.

Demo:

%echo org.gnome.Terminal.Legacy.Keybindings|sed 's/\.\|$/\//g'
org/gnome/Terminal/Legacy/Keybindings/
1

You could do

#!/bin/bash
s=org.gnome.Terminal.Legacy.Keybindings
g=$(echo $s | sed "s|\.|/|g") 
echo $(echo "$g" | sed 's@$@/@')

it searches for The end of the line ($) and replaces it with a /.

@ is an alternative seperator.

  • @ is not that readable in my opinion, I prefer ,. – Gene Pavlovsky Jul 3 '17 at 21:30
  • I prefer @ because it's the only symbol that I never needed in a script except as seperator. @GenePavlovsky – ADDB Jul 3 '17 at 21:31
1

You're doing two things with sed here:

  1. replacing all the dots with slashes, and
  2. adding a slash to the end of line

The first task may be done by the sed command y#.#/#. The y command is similar to how the tr utility works in that it replaces characters from one string to another without involving regular expressions. The three # are delimiters for the command (it usually uses /, as in y/A-Z/a-z/ to lowercase all characters in the A-Z range), but just like with the s command, we may use any delimiter we want.

The second task may be done by replacing the end of line with a slash using s#$#/#.

Putting these together, we get

sed -e 'y#.#/#' -e 's#$#/#'

In your script:

#!/bin/bash
s='org.gnome.Terminal.Legacy.Keybindings'
g=$( sed -e 'y#.#/#' -e 's#$#/#' <<<"$s" )
printf '%s\n' "$g"

This produces

org/gnome/Terminal/Legacy/Keybindings/

Of course, the slash may be put in by the printf and the replacements of the dots with slashes may be done with tr too:

#!/bin/bash
s='org.gnome.Terminal.Legacy.Keybindings'
g=$( tr '.' '/' <<<"$s" )
printf '%s/\n' "$g"
  • What is the difference between sed 's/text1/text2', sed 's:text1:text2', sed 's@text1@text2', sed 's#text1#text2', sed 's|text1|text2'? Can we use any special symbol we want or do these /:@#| have some meaning? – GypsyCosmonaut Jul 4 '17 at 8:54
  • 1
    @GypsyCosmonaut All of those contains syntax errors; the last delimiter (/, :, @ and # respectively) is missing. Apart from that, all are equivalent. You may choose whichever character you want to delimit the s command: sshellosworlds will replace hello with world, as would s/hello/world/ and s!hello!world!. It's allowed to get rid of the "leaning toothpick syndrome": s/\/var\/log\//\/usr\/var\/log\// --> s#/var/log/#/usr/var/log/#. – Kusalananda Jul 4 '17 at 8:57
  • 1
    @GypsyCosmonaut Just for fun: I looked through the dictionary for words that were sed substitution commands. sentence would replace nt with nc, for example. – Kusalananda Jul 4 '17 at 9:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.