9

The files that come in have spaces, single quotes, brackets, square brackets etc.

I remove spaces and replace with dots with the following command

for file in *.mp4; do mv "$file" `echo $file | tr ' ' '.'` ; done

Then I remove special characters with the following command

rename -n 's/[^a-zA-Z0-9_-]//g' "$file"

But for some reason single quotes(') are still present in file names. Is there a way to have clean file names in one command?

Andy
  • 583
  • 2
  • 9
  • 23
  • declare -- file="ਵੇਖੋ.ਕਤਰ.ਦੇ.ਸ਼ੇਖ.ਦੀ.ਅਮੀਰੀ,.ਪਤੀ.ਨਾਲ.ਛ-b3yttkoHl9I.mp4" – Andy Nov 21 '16 at 19:33
  • 3
    The `ls` command will automatically surround files with singly quotes(') if there name has special chars in it. Are those the single quotes you are seeing? – Tim Nov 21 '16 at 19:44
  • Nope, here is an example: Kejriwal's.stance.swiss.account.mp4 – Andy Nov 21 '16 at 19:50
  • What does `rename -n 's/.\w+$|[^a-zA-Z0-9_-]//g' "Kejriwal's.stance.swiss.account.mp4"` output for you? – anubhava Nov 21 '16 at 20:18

6 Answers6

10

In bash:

for file in *.mp4; do dest="${file//[[:space:]]/.}" && mv -i "$file" "${dest//[^[:alnum:]._-]/}"; done
nabin-info
  • 289
  • 1
  • 7
  • This does not rely on external tools like `rename` so it should be more portable. For example, `rename` on archlinux does not work like that. – nabin-info Nov 21 '16 at 20:43
  • To only target names with single quotes in them, `for file in *\'*; do mv "$file" "${file//\'/}"; done`. The [parameter expansion](https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html) `${variable//pattern/substitution}` is a Bash extension. – tripleee Mar 16 '23 at 07:41
0

sed command is one of the option for your requirement.

for file in *.mp4 ; do echo ${file}|sed -e "s/ /./g" -e "s/[\[{\\']//g" ; done

Example:

$ for file in *.mp4 ; do echo $file; done
as {df [jk \'hj.mp4
as {df[jk \'hj.mp4
as {df[jk\'hj.mp4
as {df [jk \'.mp4
$
$ for file in *.mp4 ; do echo ${file}|sed -e "s/ /./g" -e "s/[\[{\\']//g" ; done
as.df.jk.hj.mp4
as.dfjk.hj.mp4
as.dfjkhj.mp4
as.df.jk..mp4
$
learner
  • 119
  • 1
  • 2
  • 12
0

If you need to rename files recursively, i.e. rename all files in a directory tree starting from the current directory, you need to wrap the command in find. Here is a simple version which works if you have Bash available.

find . -d -name "*'*" -exec bash -c $'for f; do
    mv "$f" "${f//\\\047/}"; done' _ {} +

If you don't have Bash, you need something like

find . -d -name "*'*" -exec sh -c 'for f; do
    mv "$f" "$(echo "$f" | tr -d \'\'')"; done' _ {} +

which is slightly more expensive because it runs an external tr command for each file. (Also, the quoting here is mildly challenging, to get a literal single quote passed as the argument to tr inside a shell script in single quotes.)

The -d option to instruct find to do a depth-first search is important because it prevents you from attempting to rename a file whose parent directory has been renamed slightly earlier, which would fail because the old path no longer exists under the original name.

(The newline in the middle of the command is just for improved legibility on small screens; you can make it a one-liner if you like.)

The wildcard "*'*" targets all files with a single quote in them; if you only want to process "*'*.mp4" or "*'*.mp4'" then obviously use one (or both) of those wildcards instead. Here's how you can combine them:

find . -d \( -name "*'*.mp4" -o -name ""*'*.mp4" \) -exec ...
tripleee
  • 175,061
  • 34
  • 275
  • 318
0

To get rid of double quotes in file name use the mv command:

for file in *; do mv "$file" "${file/\"/}"; done

It should work for single quotes as well.

This will apply to all files in the folder (ie., for file in *; do).

The syntax ${file/\"/} means: Take all file names, search for " (make sure to include the backslash) and then replace it with nothing. If you wanted to replace all quotes with an underscore for example, the line would be ${file/\"/_}.

To get rid of single quotes run:

for file in *; do mv "$file" "${file/\'/}"; done

Hope this helps!

ahuemmer
  • 1,653
  • 9
  • 22
  • 29
MaggsX
  • 1
-1

mv ./'file' newfile

works for a single file

  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Nov 17 '22 at 13:19
-1

IMPORTANT! This is easily overlooked if not anticipated: Files coming from a Windows machine that contain spaces are represented on Linux with a single quote at each end. These single quotes "ARE NOT PART OF THE FILE NAME"! This is a no no on Linux, so use this command to replace the single quotes with underscores in order to make the files "real/legitimate":

sudo rename "s/\ /_/g" *  #Replaces spaces with underscores to convert to Unix/Linux-style "real" filenames

Don't laugh at this! It's surprising how often this sort of oversight happens and how much time is wasted trying to figure out why none of the so-called proven solutions work, although it seems they should! We seldom, or don't expect to see spaces in Linux filenames, and so the "paradigm / force of habit syndrome" prevents us from noticing them. Every computer person understands fighting syntax, but this is another, tangential concern, that we must keep in mind.

If something does not work, there is always a reason ... often one that should have been obvious!

tripleee
  • 175,061
  • 34
  • 275
  • 318
SandPond
  • 1
  • 2
  • This is rather confused. Linux handles file names with spaces just fine and there are very few situations where something would add single quotes around them. If you don't understand quoting, such file names can be slightly hard to handle, but the fix for that is to learn how to use quoting in the shell. See also [When to wrap quotes around a shell variable](https://stackoverflow.com/questions/10067266/when-to-wrap-quotes-around-a-shell-variable) and https://mywiki.wooledge.org/BashFAQ/020 – tripleee Mar 16 '23 at 07:22
  • Separately, the use of `sudo` here seems misdirected and even potentially dangerous. – tripleee Mar 16 '23 at 07:23
  • In fact, some versions of `ls` will add single quotes around file names with spaces in them. You can see the _actual_ file names with `ls -N` or `printf '%s\n' *` (you might want to use `printf '%q\n' *` to get a display which escapes any spaces etc, though then of course the backslashes in the output will similarly need to be understood correctly; an actual literal backslash would be displayed as two backslashes in this output). – tripleee Mar 16 '23 at 08:16