Finding All .mp3 Files And Move To a New Directory From A Shell Prompt
have mp3 music files all over my file system. I would like to move them into specific directory called /mnt/mp3. So how do you find and move all mp3 files to /mnt/mp3 directory on Linux or Unix-like system?
Simply use the find command. It locates all files and then executes a command to move each mp3 file to /mnt/mp3 directory.
Warning: Backup all your data before you type the following commands.【操作之前先备份!】
Step # 1: Finding all your .mp3 files
The following command will just find all your .mp3 files using the find command:
# find / -iname "*.mp3" -print
Where,
- / – Search / root directory
- -iname – File name search pattern (case insensitive)
- -print – Display name of files on screen
Step # 2: Finding and moving all your .mp3 files in one single pass
Type the following command to find and move all files using mv command to /mnt/mp3 directory:
# find / -iname "*.mp3" -exec mv {} /mnt/mp3 ;
Where,
- -exec mv {} /mnt/mp3 ; : Execute mv command.(字符串”{}”最后会被匹配出的文件名替换;而字符串”;”则表示mv命令结束)
- The string ‘{}’ is replaced by the file name
- ; ends /bin/mv command
To just move .mp3 files and not directories, use:
# find / -iname "*.mp3" -type f -exec /bin/mv {} /mnt/mp3 ;
Find all directories having name mp3 and move:
# find / -iname "*.mp3" -type d -exec /bin/mv {} /mnt/mp3 ;
For performance you may need to consider using xargs command(这里添加了xargs的 “-I” 选项,防止当匹配出的文件名中包含空格时后面的命令执行出现错误,以换行符作为传入参数的结束标志):
find / -iname "*.mp3" -type f | xargs -I '{}' mv {} /mnt/mp3
Sp to moves all .mp3 files with special characters in its name such as white spaces try(xargs命令的-0参数是为了防止匹配出的文件名中含有特殊字符而出现错误,这个选项一般和find命令的-print0选项一起使用):
find / -iname "*.mp3" -type f -print0 | xargs -0 -I '{}' /bin/mv "{}" /mnt/mp3/
Final solution(使用rsync替换简单的mv命令)
Above commands will not maintain sub-directory structure. Try replacing mv with rsync to use the same directory structure on the target directory with the -R option:
find / -iname "*.mp3" -type f -print0 | xargs -0 -I '{}' /usr/bin/rsync -avR "{}" /mnt/mp3/
You can also write a script that moves files along with directories. This is also useful to move all files to mp3 playerthat has been mounted on /mnt/mp3 directory.
xargs: How To Control and Use Command Line Arguments
I am trying to use xargs command using shell pipes and not able to understand how to control and use command line arguments. For example I’d like to find out all *.c file located in 100s of sub-directories and move them to another directory called ~/old.src. How do I use command line args with xargs to achieve the same?
xargs command is designed to construct argument lists and invoke other utility. xargs reads items from the standard input or pipes, delimited by blanks or newlines, and executes the command one or more times with any initial-arguments followed by items read from standard input. Blank lines on the standard input are ignored.
xargs is more safer and easy to use
xargs functionality can be achived using the backquote feature of shell. But, it offers more options. It can deal with blanks or special characters in file names easily. It is often used with find, grep and other commands.
xargs examples
For example following example will print 1 2 3 4 using xargs (echo command is default)
$ echo 1 2 3 4 | xargs echo
OR
$ echo 1 2 3 4 | xargs
You can force xargs to use at most max-args arguments per command line. For example following will use first two argument per command:
$ echo 1 2 3 4 | xargs -n 2
Find all .bak files in or below the current directory and delete them.
$ find . -name "*.bak" -type f -print | xargs /bin/rm -f
{} as the argument list marker
{} is the default argument list marker.({}是默认的参数列表标志) You need to use {} this with various command which take more than two arguments at a time. For example mv command need to know the file name. The following will find all .bak files in or below the current directory and move them to ~/.old.files directory:
$ find . -name "*.bak" -print0 | xargs -0 -I {} mv {} ~/old.files
You can rename {} to something else.(我们可以对{}进行重命名) In the following example {} is renamed as file. This is more readable as compare to previous example:
$ find . -name "*.bak" -print0 | xargs -0 -I file mv file ~/old.files
Where,
- -0 If there are blank spaces or characters (including newlines) many commands will not work. This option take cares of file names with blank space.
- -I Replace occurrences of replace-str in the initial-arguments with names read from standard input. Also, unquoted blanks do not terminate input items; instead the separator is the newline character.(-I选项设置后,参数名中最末尾的空白符将不再用于终止输入,参数列表分隔符被替换成了换行符)
Dealing file names with blank spaces and newline
The following will work incorrectly if there are any filenames containing newlines or spaces (当文件名中包含换行符和空格时该命令执行将会出错)(it will find out all .mp3 file located in current directory and play them using mplayer):
$ find . -iname "*.mp3" -print | xargs mplayer
To get rid of this problem use -0 option(可以和find命令中的-print0选项联合使用以避免错误):
$ find . -iname "*.mp3" -print0 | xargs -0 -I mp3file mplayer mp3file
To find out all *.c file located in 100s of subdirectories and move them to another directory called ~/old.src, use:
$ find /path/to/dir -iname "*.c" -print0 | xargs -0 -I file mv file ~/old.src
Avoiding errors and resource hungry problems with xargs and find combo
To copy all media files to another location called /bakup/iscsi, you can use cp as follows:
$ cp -r -v -p /share/media/mp3/ /backup/iscsi/mp3
However, cp command may fail if an error occurs such as if the number of files is too large for the cp command to handle. xargs in combination with find can handle such operation nicely. xargs is more resource efficient and will not halt with an error(当cp命令的参数过多时执行起来就会出错,这时就需要使用find和xargs命令的组合来处理这一问题):
$ find /share/media/mp3/ -type f -name "*.mp3" -print0 | xargs -0 -r -I file cp -v -p file --target-directory=/bakup/iscsi/mp3
Please note that all of the above commands are tested with GNU/xargs version. BSD and UNIX xargs command may not have options such as -r. Please refer to your local xargs man page for further info:
man xargs
mkdir $DIR2/$i;
find $DIR2 -type f -newermt $i -print0 | xargs -0 mv -t $DIR2/$i
done
mkdir $DIR2/$i;
find $DIR2 -type f -newermt $i -print0 | xargs -0 mv {} $DIR2/$i
done
mv [OPTION]… [-T] SOURCE DEST
mv [OPTION]… SOURCE… DIRECTORY
mv [OPTION]… -t DIRECTORY SOURCE…
《“一行命令解决:查找系统中所有的MP3文件并将其移动至某一新的目录中”》 有 1 条评论
Linux下find命令使用-exec选项时的一些注意事项
Using semicolon (;) vs plus (+) with exec in find
https://stackoverflow.com/questions/6085156/using-semicolon-vs-plus-with-exec-in-find