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?

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
  • 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 9 '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 3:06

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.