1

I have a number of Windows based .m3u playlists - they start with ..\..\ and have \ instead of / for folder paths, whereas Ubuntu prefers they start with /media/usr/part/dir/ (i.e. the absolute path).

I want to make the following changes

  1. Replace all ..\..\ with /media/usr/part/dir/
  2. Replace all \ with /

I tried using find /home/user/directory -name \*.m3u -exec sed -i "s/\.\.\\\.\.\/\/media\/usr\/part\/dir\//g" {} \; as suggested here, and tried using _ and : as delimiters as suggested here.

However, I keep getting

sed: -e expression #1, char 36: unterminated `s' command

How do I make the necessary replacements in my files?

3l4ng
  • 886

1 Answers1

2
s/\.\.\\\.\.\/\/media\/usr\/part\/dir\//g

This sed command is wrong, because it has a missing \ before the first /, which leads the preceding \ to escape it as a literal / (changing the pattern and "eating" the separator) and, for the purpose of replacing a single occurence of ..\..\ on each line, it has an excessive g switch at the end; in any case it's missing the replacement of the \ characters with the / character part.

Use this one instead; I've took the liberty of changing the separator to get rid of a likely sudden leaning toothpick syndrome and to change ; with + to improve the command's performance over a huge number of files:

find /home/user/directory -name \*.m3u -exec sed -i 's|\.\.\\\.\.\\|/media/usr/part/dir/|; s|\\|/|g' {} \+

Output:

~/tmp$ cat playlist1.m3u 
..\..\path1
stuff
..\..\path2\path2
stuff
..\..\path3\path3\path3
stuff
~/tmp$ find . -name \*.m3u -exec sed -i 's|\.\.\\\.\.\\|/media/usr/part/dir/|; s|\\|/|g' {} \+
~/tmp$ cat playlist1.m3u 
/media/usr/part/dir/path1
stuff
/media/usr/part/dir/path2/path2
stuff
/media/usr/part/dir/path3/path3/path3
stuff
kos
  • 35,891
  • worked like charm. Thanks !

    I had no idea sed replacemets could be given on the same line in a python-ish manner. And I don't need to use // when I want to replace a frontslash (i.e. / char) in the file ?

    – 3l4ng Jul 09 '15 at 20:05
  • @3l4ng Usually yes (but not with a slash, with a backslash) because usually slashes are used as the separator, and if not escaped when used as a literal / they are interpreted as the separator (much like it happened with your command): I changed the separator to | exactly because of that, because using / would have lead to this (less intelligible) command: s/\.\.\\\.\.\\/\/media\/usr\/part\/dir\//; s/\\/\//g – kos Jul 10 '15 at 03:06