Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

It was a mess of music files and directory.

It is needed to perform the below operation over multiple directories at once:

  1. If the directory contains ".jpg" files, then create a new directory "Covers" and move those files into it.
  2. If the directory does not contain any ".jpg" files, don't create "Covers" directory
  3. If the directory already contains "Covers" directory, don’t create "Covers" directory
share|improve this question
add comment

3 Answers 3

up vote 3 down vote accepted

In bash:

#!/bin/bash
shopt -s nullglob
for dir; do
    [[ -d $dir ]] || continue
    jpgs=( "${dir}"/*.jpg )
    if (( "${#jpgs[@]}" )); then
        [[ -d ${dir}/Covers ]] || mkdir "${dir}/Covers"
        # Avoiding race condition by not reusing the jpgs array
        for jpg in "${dir}"/*.jpg; do
            mv "$jpg" "${dir}/Covers"
        done
    fi
done
share|improve this answer
    
pretty simple and neat, @Chris-down :-) –  Nikhil Mulley Mar 3 '12 at 10:43
    
@Chris-down, darn that is awesome :) –  user14517 Mar 3 '12 at 14:16
    
@Chirs Down, Awesome sir :) –  user1228191 Mar 3 '12 at 15:09
add comment

I am still a rookie but here is mine:

#!/bin/bash
current_directory=$(pwd)
#echo $current_directory
(find -maxdepth 1 -type d -name '*' ! -name '.*' -printf '%f\n')>filelist
number=$(find -maxdepth 1 -type d -name '*' ! -name '.*' -printf '%f\n' | wc -l)
for iteration in `seq $number`
do
    fname=$(head -1 filelist)
    sed 1d < filelist > filelist2
    mv filelist2 filelist
    cd "$fname"
    if [ -z $(ls | grep -i jpg) ]
    then echo "Doing nothing as there are no JPG files....."
    else
        total=$(ls -l|grep -i jpg | wc -l)
        mkdir -p Covers
        mv *.jpg Covers
        echo "Moved $total JPG Files....."
    fi
    cd "$current_directory"
done  

Simply go into the main music directory and execute this script.

No need to pass any arguments

EDIT: It was sloppy before. It is sloppier now. But I think it will work.

share|improve this answer
    
Thanks its very nice, Same question for you too : How to get handle those directory names which contains spaces in its name –  user1228191 Mar 3 '12 at 9:34
    
Oh. Nice catch. I'll work on it. –  user14517 Mar 3 '12 at 9:53
    
Do not parse ls, it is dangerous and will break easily. Use a glob. See mywiki.wooledge.org/ParsingLs –  Chris Down Mar 3 '12 at 10:18
1  
Also, you need to quote $current_directory, or it will break if the path has spaces in. –  Chris Down Mar 3 '12 at 10:34
1  
Yes, it will. Don't parse ls! –  Chris Down Mar 3 '12 at 11:02
show 1 more comment
#!/bin/bash  

SAVEIFS=$IFS  
IFS="\n\b"  
#-----------------------------------------------------------------------------  

#work in current dir if work path was not provided  
[ $# -eq 0 ] && search_path="." || search_path="$1"  


# files to be moved, more extensions can be added  
wildcard="*[jpg|JPG]"  


move_jpg() {  
    # create "Covers" if it doesn't exist  
    [ -d "$1/Covers" ] && echo -n " ... " || { echo -n " ...create Covers ";   mkdir "$1/Covers" }  

    mv "$1/$wildcard" "$1/Covers/$wildcard"  
    echo "... files moved"  
}  



for d in "$search_path/*/"; do  

    echo -n "testing <$d>   "  

    [ -e "$d/$wildcard" ] && ${move_jpg "$d"} || echo "...Not found <$wildcard>"  

done  



#-----------------------------------------------------------------------------  
IFS=$SAVEIFS  
share|improve this answer
1  
Using command substitution with find will break very easily. Do not do it. –  Chris Down Mar 3 '12 at 10:19
    
Instead of calling find, which will break on all kinds of file names, write for d in "$search_path"/*/; the final / restricts the matching to directories. I wonder where IFS=$(echo -en "\n\b") comes from (by the way, you can write this in a simpler way: IFS=$'\n\b'): what's the point in making backspace a field separator? –  Gilles Mar 3 '12 at 23:51
    
didn't know about trick with last slash, will use it, thanks. of cause, IFS=$(echo ...) can be easily replaced to just assignement. corrected. –  vasily-vm Mar 6 '12 at 16:53
    
"Using command substitution with find will break very easily" don't understand this :( how find can be broken in such situation? –  vasily-vm Mar 6 '12 at 16:57
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.