简体   繁体   中英

Move files to directories based on extension

I am new to Linux. I am trying to write a shell script which will move files to certain folders based on their extension , like for example in my downloads folder, I have all files of mixed file types. I have written the following script

mv *.mp3 ../Music
mv *.ogg ../Music
mv *.wav ../Music
mv *.mp4 ../Videos
mv *.flv ../Videos

How can I make it run automatically when a file is added to this folder? Now I have to manually run the script each time.

One more question, is there any way of combining these 2 statements

mv *.mp3 ../../Music
mv *.ogg ../../Music

into a single statement? I tried using || (C programming 'or' operator) and comma but they don't seem to work.

There is no trigger for when a file is added to a directory. If the file is uploaded via a webpage, you might be able to make the webpage do it.

You can put a script in crontab to do this, on unix machines (or task schedular in windows). Google crontab for a how-to.

As for combining your commands, use the following:

mv *.mp3 *.ogg ../../Music

You can include as many different "globs" (filenames with wildcards) as you like. The last thing should be the target directory.

Two ways:

  1. find . -name '*mp3' -or -name '*ogg' -print | xargs -J% mv % ../../Music
  2. find . -name '*mp3' -or -name '*ogg' -exec mv {} ../Music \\;

The first uses a pipe and may run out of argument space; while the second may use too many forks and be slower. But, both will work.

I like this method:

#!/bin/bash                                                                                                                                                                                                 

for filename in *; do
  if [[ -f "$filename" ]]; then
      base=${filename%.*}
      ext=${filename#$base.}
    mkdir -p "${ext}"
    mv "$filename" "${ext}"
  fi
done

incron will watch the filesystem and perform run commands upon certain events.

You can combine multiple commands on a single line by using a command separator. The unconditional serialized command separator is ; .

command1 ; command2

Another way is:

mv -v {*.mp3,*.ogg,*.wav} ../Music
mv -v {*.mp4,*.flv} ../Videos

PS: option -v shows what is going on (verbose).

You can use for loop to traverse through folders and subfolders inside the source folder. The following code will help you move files in pair from "/source/foler/path/" to "/destination/fodler/path/". This code will move file matching their name and having different extensions.

for d in /source/folder/path/*; do
    ls -tr $d |grep txt | rev | cut -f 2 -d '.' | rev | uniq | head -n 4 | xargs -I % bash -c 'mv -v '$d'/%.{txt,csv} /destination/folder/path/'
    sleep 30
done 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM