6

Many files in a directory (/root/path/) have a strange character string appended to them (\#015). Help me replace them with regular names without the strange string.

I need:

/root/path/img1.png\#015
/root/path/img2.jpg
/root/path/img3.png\#015

To be:

/root/path/img1.png
/root/path/img2.jpg
/root/path/img3.png

Can you help?

Ryan
  • 14,682
  • 32
  • 106
  • 179
  • My issue was resolved by converting end of line (EOL) from Windows to Unix in a `rsync` bash script that was failing - commenting because this answer was first thing that showed up in search. – Daniel Sokolowski Apr 28 '19 at 16:41

4 Answers4

5
for file in *\#015
do
   mv -- "$file" "${file%\#015}"
done

You may need to escape the "\"s. Try it in a tmp directory first.

Ed Morton
  • 188,023
  • 17
  • 78
  • 185
5

If you have rename installed, this becomes a fairly simple task:

rename 's/\\#015$//' /root/path/*\\#015

You can add the -f flag to force overwriting existing files if necessary.

Steve
  • 51,466
  • 13
  • 89
  • 103
1

This is how I'd solved a similar problem in the past with a little shell.

cd /root/path/
ls | grep '\#015' | sed 's/\(.*\)\\#015/mv & \1/' | sh
Matt Kelly
  • 91
  • 3
  • and of course, Ryan, you'd leave off the trailing `| sh`, so you could look at the commands 'that will be executed' until you were certain that those commands will not have unintended consequences, right? ;-) Good luck to all. – shellter Nov 16 '12 at 16:52
  • Instead of `ls | grep '\#015'`, it'd be more natural to use `ls *\#015`. I wouldn't use the approach anyway though since a simple shell loop is all you need. – Ed Morton Nov 16 '12 at 17:11
0

You can do it with find and parameter substitution as follows:

#!/bin/bash

find -name '*\\#015' | while IFS= read -r f
do
    mv -- "${f}" "${f%?????}"
done
  • Put the above code in a script called my_script.sh in your /root/path/, and run it by chmod +x my_script.sh && ./my_script.sh
  • Note that this will apply the changes recursively to all subfolders under /root/path/ as well.

Explanation:

  • find -name '*\\#015': find all files ending with \#015
  • Then for each such file found: mv "${f}" "${f%?????}" renames it from the old name to a new name with the last 5 characters in the file name removed.
sampson-chen
  • 45,805
  • 12
  • 84
  • 81
  • Remember to quote your variables unless you have a very specific reason not to. The above will fail if your file name contains spaces or any globbing characters or start with a - sign. – Ed Morton Nov 16 '12 at 16:56
  • @EdMorton Good call. Editing that now. – sampson-chen Nov 16 '12 at 16:58
  • Stick a `--` after `mv`. More importantly though, your loop will not work as written. You need to write it as `find -name '*\\#015' | while IFS= read -r file`. – Ed Morton Nov 16 '12 at 17:09
  • to clarify, you can't do `for f in $files` or it will fail for file names that contains spaces and do globbing, but neither can you do `for f in "$files"` or all file names will be concatenated into one string. Hence the need for piping the find output to a while read loop. It will still fail for file names that contain newlines, you'd need to use xargs or find -exec to get around that, but it's all getting probably needlessly complicated. `for file in *` is the way to go if possible as it's clear, simple, and foolproof. – Ed Morton Nov 16 '12 at 17:15
  • @EdMorton thanks for pointing that out. Could you elaborate a bit on `while IFS= read -r file`? I'm assuming that sets the internal field separator to " "? (but isn't IFS space by default?) Also, is there a resource you could point me to for reading up on `read`? I tried looking but results are saturated with the syscall instead. – sampson-chen Nov 16 '12 at 17:22
  • It sets IFS to the null string so no field splitting occurs. read -r just tells read to work in raw mode. Between the 2 you get your variable populated with exactly what was input. I'd have expected the man page for your shell would talk about it. – Ed Morton Nov 16 '12 at 17:28
  • @sampson-chen, `read` is actually a shell builtin, so `help read` would be of use here. – doubleDown Nov 18 '12 at 03:43