0

I am using Ubuntu 20.04.2 with GNU sed version 4.7. I have a bunch of music files that got named weirdly because they did not have all the info I specified to be in the file name. For example, "Bruno Mars - NA - Bruno Mars - The Lazy Song.aiff" Basically, the NA is put in place of the year because that is unknown. What I want to do is rename all of these files to omit the "- NA -" and everything before that, so the file comes out to be "Bruno Mars - The Lazy Song.aiff"

Here is my problem and what I have tried so far: I coppied a few of the affected files to a different folder and used the command sed 's/^.*NA -//' * to try and fix the naming, but I started to get very weird output from the terminal, see this. I have tried reinstalling sed, using rename sed 's/^.*NA -//' * and perl -pi -e 's/^.*NA -//' * and none of them have worked; however, the rename and perl commands have not produced the same, weird output as before. My gut is telling me that my regex is incorrect, but the documentation says that this should work. Any help is appreciated. Thanks!

  • 2
    sed 's/^.*NA -//' * would not rename files, it would attempt to replace the pattern in the files' contents, streaming the result to the terminal (with potentially weird results, especially if the expansion of * includes any binary files). – steeldriver May 04 '21 at 19:34
  • 1
    You want to use the rename command, not sed: see https://manpages.ubuntu.com/manpages/focal/en/man1/prename.1p.html – glenn jackman May 04 '21 at 19:58
  • @glennjackman That sounds like an answer. – mchid May 04 '21 at 20:10
  • You have a pastebin error: Error, this is a private paste or is pending moderation. If this paste belongs to you, please login to Pastebin to view it. – mchid May 04 '21 at 20:11
  • perfect job for mmv... mmv '* - NA - *.aiff' '#2.aiff' –  May 05 '21 at 06:18

1 Answers1

1

The command sed 's/^.*NA -//' * would not rename files, it would attempt to replace the pattern in the files' contents, streaming the result to the terminal (with potentially weird results, especially if the expansion of * includes any binary files).

The command perl -pi -e 's/^.*NA -//' * would do the same, except modifying the contents in place, possibly corrupting your files.

To use sed (or perl itself) for file renaming, you'd need to do something like

for f in *; do mv -n -- "$f" "$(sed 's/pattern/replacement' <<<"$f")"

or

for f in *; do mv -n -- "$f" "$(printf '%s\n' "$f" | sed 's/pattern/replacement')"

i.e. passing the name of each file to sed via standard input. However your pattern could just as easily be written as a shell substitution, eliminating the need for sed altogether:

for f in *; do mv -n -- "$f" "${f##* - NA - }"; done

(I'm assuming you want to remove the leading space as well). The ##* matches the longest leading character sequence, equivalent to basic regular expression ^.*

To use perl under the hood, but modifying file names rather than contents, you'd want the rename command, from package rename. (There are other rename commands, such as the one from package util-linux that work differently.) For example:

rename -n 's/^.*? - NA - //' *.aiff

(I limited the scope to .aiff files, and made the .* match non-greedy - a feature that sed does not provide - so that it only matches up to the first - NA - in case there are multiple instances.) Remove the -n once you are satisfied with the proposed re-namings.

steeldriver
  • 136,215
  • 21
  • 243
  • 336