我有一系列TXT
文件,位于一系列遵循命名方案的子目录中
-Incoming
|-Office-August.2020
|--Office-August.2020.txt
|-Office-September.2020
|--Office-September.2020.txt
|-Office-October.2020
|--Office-October.2020.txt
|-Branch-August.2020
|--Branch-August.2020.txt
|-Branch-September.2020
|--Branch-September.2020.txt
|-Branch-October.2020
|--Branch-October.2020.txt
我想编写一个脚本来定期将所有TXT
文件根据其文件名移动到一系列目录中,例如:
-Documents
|-Office
|--Office-August.2020.txt
|--Office-September.2020.txt
|--Office-October.2020.txt
|-Branch
|--Branch-August.2020.txt
|--Branch-September.2020.txt
|--Branch-October.2020.txt
然后我想删除旧的子目录和任何剩余的文件。我仍在学习 Bash 脚本,所以我不太清楚如何实现这一点,但这是我目前想到的办法。它找到了文件,但还不能移动它们。
#!/bin/bash
INPUT=~/Incoming
OUTPUT=~/Documents
find $INPUT -type f -name "*.txt" | while IFS= read -r filename; do
case $filename in
Office*) mv "$filename" "$OUTPUT/Office/" ;;
Branch*) mv "$filename" "$OUTPUT/Branch/" ;;
*) echo "don't know where to put $filename";;
esac
done
有什么建议么?
编辑*
:如果我在 case 语句的行首添加 ,我就可以移动文件Office*) mv "$filename" "$OUTPUT/Office/" ;;
,因为我意识到正在读取的文件名包含完整路径,而不是以 Office 或 Branch 开头。现在该行显示*Office*) mv "$filename" "$OUTPUT/Office/" ;;
。所以,现在我想知道是否有更好的方法可以编写该find .... | while ...
行以仅标识文件名,而不是完整路径。
答案1
- 您可以使用find命令来查找并复制所有找到的文件。
- 语法是
find <PATH-OF-THE-FILES-TO-COPY> -iname <NAME> -exec cp {} <PATH-COPY-THE-FILES-TO> \;
- 命令示例
find /home/xthudrsdayx/Office/ -iname *.txt -exec cp {} /home/xthudrsdayx/txt/ \;
- 命令示例
- 评论:
-exec cp
是对所有创建的文件执行cp命令。- 星号(*)表示在 * 位置上的任意 ASCHII 组合。
find
您可以在 中使用更多命令过滤器man find
。
- 希望这就是您所寻找的,如果出现问题或无法理解,请发表评论,以便我们一起尝试解决。
答案2
basename $filename
剥离路径
因此,为了完整起见,例如
mv `basename "$filename"`;;
在你的case
答案3
find -execdir
将在执行命令之前将目录更改为文件所在的位置。如果您的文件格式正确,则可以使用文件${2%%-*}
Office -August.2020.txt的开头来构建目标目录。
$ find Incoming/ -mindepth 1 -type f -name '*.txt' \
-execdir bash -c 'mkdir -p $1/${2%%-*}; mv -nt $_ $2' _ $PWD/Documents {} \;
^ ^ ^ ^
Last argument from the previous command $0 $1 $2