我目前正在学习 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/