Move files to directories based on first part of f

2019-03-12 20:03发布

问题:

I have several thousand ebooks that need to be organized on a headless linux server running bash through SSH. All of the ebooks are thankfully named with one of 2 conventions.

  • AuthorFirstName AuthorLastName - Book Title.pdf
  • AuthorFirstName AuthorLastName - Book Series #inSeries - Book Title.pdf

What I would like to do is to move all of the books into an organized system such as:

`DestinationDirectory/FirstLetterOfAuthorFirstName/Author Full Name/pdf's`

e.g. the following books

Andrew Weiner - Changes.pdf 
Allan Cole - Timura Trilogy 01 - When the Gods Slept.pdf

should be placed in the following folders

/books/A/Allan Cole/Allan Cole - Timura Trilogy 01 - When the Gods Slept.pdf
/books/A/Andrew Weiner/Andrew Weiner - Changes.pdf

I need help with how to put this all into a bash script that will grab the filenames of all the PDF files in the current directory, and then move the files to the proper directory, creating the directory if it doesn't already exist.

回答1:

for f in *.pdf; do
    name=`echo "$f"|sed 's/ -.*//'`
    letter=`echo "$name"|cut -c1`
    dir="DestinationDirectory/$letter/$name"
    mkdir -p "$dir"
    mv "$f" "$dir"
done


回答2:

Actually found a different way of doing it, just thought I'd post this for others to see/use if they would like.

#!/bin/bash
dir="/books"
if [[ `ls | grep -c pdf` == 0 ]]
then
        echo "NO PDF FILES"
else
        for src in *.pdf
        do
                author=${src%%-*}
                authorlength=$((${#author}-1))
                letter=${author:0:1}
                author=${author:0:$authorlength}
                mkdir -p "$dir/$letter/$author"
                mv -u "$src" "$dir/$letter/$author"
        done
fi


回答3:

@OP you can do it with just bash

dest="/tmp"
OFS=$IFS
IFS="-"
for f in *.pdf
do
    base=${f%.pdf}
    letter=${base:0:1}
    set -- $base
    fullname=$1
    pdfname=$2
    directory="$dest/$letter/$fullname"
    mkdir -p $directory
    cp "$f" $directory
done
IFS=$OFS


回答4:

for i in *.pdf; do
  dir=$(echo "$i" | \
    sed 's/\(.\)\([^ ]\+\) \([^ ]\+\) - \(.*\)\.pdf/\1\/\1\2 \3/')
  dir="DestinationDirectory/$dir"
  mkdir -p -- "$dir" && mv -uv "$i" "$dir/$i"
done