按类别将文件从源移动到目标

按类别将文件从源移动到目标

我目前正在学习 bash 脚本,并尝试编写一个脚本,将文件从源移动到目标目录,并根据首字母对文件进行分类,并根据首字母创建子目录。

类别:

  • 自动对焦
  • GL
  • 先生
  • 深圳
  • #

这是我目前所写的,但我不确定如何继续:

移动脚本

echo "Enter the source"
read SOURCE

echo "Enter the destination"
read DESTINATION

for file in $SOURCE;do
    case ${file:0:1} in
      {a..f} ) echo "Belongs to A-F";
        if [ -d $DESTINATION/A-F ]
        then mv file $DESTINATION/A-F
        else mkdir $DESTINATION/A-F
      {g..l} ) echo "Belongs to G-L";
        if [ -d $DESTINATION/G-L ]
        then mv file $DESTINATION/G-L
        else mkdir $DESTINATION/G-L
      {m..r} ) echo "Belongs to M-R";
        if [ -d $DESTINATION/M-R ]
        then mv file $DESTINATION/M-R
        else mkdir $DESTINATION/M-R
      {s..z} ) echo "Belongs to S-Z";
        if [ -d $DESTINATION/S-Z ]
        then mv file $DESTINATION/S-Z
        else mkdir $DESTINATION/S-Z
        { } ) echo "Belongs to #";
        if [ -d $DESTINATION/# ]
        then mv file $DESTINATION/#
        else mkdir $DESTINATION/#
    esac
exit 0

例子:

我已经下载了 Downloads 目录中的文件

aa1.jpg、gg2.mp3、zo1.mkv、01010.pdf

sh move.sh 


Enter the source
/Downloads

Enter the destination
/Documents

运行脚本后,我应该得到:

/Documents/#/01010.pdf
/Documents/A-F/aa1.jpg
/Documents/G-L/gg2.mp3
/Documents/S-Z/zo1.mkv

答案1

我注意到你的脚本中存在一些错误:

这应该会产生您想要的结果:

#!/bin/bash

echo "Enter the source"
read SOURCE

echo "Enter the destination"
read DESTINATION

for file in $SOURCE/*; do
  base=`basename "${file}"`
  letter=${base:0:1}

  case $letter in
    [a-f]) echo "A-F";
     if [ -d "$DESTINATION/A-F" ]; then
       echo "Moving file..."
       mv $file "$DESTINATION/A-F"
     else
      mkdir -p "$DESTINATION/A-F";
     fi
    ;;
    [g-l]) echo "G-L"
      if [ -d "$DESTINATION/G-L" ]; then
        echo "Moving file..."
        mv $file "$DESTINATION/G-L"
      else
        mkdir -p "$DESTINATION/G-L"
      fi
    ;;
    [m-r]) echo "M-R"
      if [ -d "$DESTINATION/M-R" ]; then
        echo "Moving file..."
        mv $file "$DESTINATION/M-R"
      else
        mkdir -p "$DESTINATION/M-R"
      fi
    ;;
    [s-z]) echo "S-Z";
      if [ -d "$DESTINATION/S-Z" ]; then
        echo "Moving file..."
        mv $file "$DESTINATION/S-Z"
      else
        mkdir -p "$DESTINATION/S-Z";
      fi
    ;;
    *) echo "-"
      if [ -d "$DESTINATION/-" ]; then
        echo "Moving file..."
        mv $file "$DESTINATION/-"
      else
        mkdir -p "$DESTINATION/-";
      fi
  esac
done

答案2

我建议制作目录尝试移动文件,而不是之后。另外,跳过检查目录是否存在,只需使用

mkdir -p

另外,我认为你不需要所有这些复杂的条件,尽管我认为简单性取决于旁观者的想法。对我来说,类似下面的内容似乎更简单。

#!/bin/bash

# repeats until you enter a valid directory
while [ ! -d "$DESTINATION_ANY_VALID_FORM" ]; do
      read -p "Enter destination directory:" DESTINATION_ANY_VALID_FORM
done

# canonicalizes directory name into a standard form
DESTINATION="$(readlink -f "$DESTINATION_ANY_VALID_FORM")"

# same deal for source
while [ ! -d "$SOURCE_ANY_VALID_FORM" ]; do
      read -p "Enter source directory:" SOURCE_ANY_VALID_FORM
done

SOURCE="$(readlink -f "$SOURCE_ANY_VALID_FORM")"

# makes the directories you want if they don't exist already - 
# conditionals aren't needed.
mkdir -p $DESTINATION/A-F
mkdir -p $DESTINATION/G-L
mkdir -p $DESTINATION/M-R
mkdir -p $DESTINATION/S-Z
mkdir -p $DESTINATION/#

# And then move the files any way you want. There must eleventy-twelve ways. 
# I was wrong thinking wildcards would be easy. 
# That is actually kind of hard. 
# The following is easy to write and understand, but there are more efficient ways.

ls -w1 "$SOURCE" | grep ^[a-f,A-F] | while read FILE ; do
       mv --verbose --backup --target-directory="$DESTINATION/A-F" "$SOURCE/$FILE"  
done

ls -w1 "$SOURCE" | grep ^[g-l,G-L] | while read FILE ; do
       mv --verbose --backup --target-directory="$DESTINATION/G-L" "$SOURCE/$FILE"  
done

ls -w1 "$SOURCE" | grep ^[m-r,M-R] | while read FILE ; do
       mv --verbose --backup --target-directory="$DESTINATION/M-R" "$SOURCE/$FILE"
done

ls -w1 "$SOURCE" | grep ^[s-z,S-Z] | while read FILE ; do
       mv --verbose --backup --target-directory="$DESTINATION/S-Z" "$SOURCE/$FILE"
done

ls -w1 "$SOURCE" | grep ^[0-9] | while read FILE ; do
       mv --verbose --backup --target-directory="$DESTINATION/#" "$SOURCE/$FILE"
done

paste-bin 版本:https://paste.ubuntu.com/24540558/

相关内容