【问题标题】:SH script to move files from one dir to another depending on the filenameSH脚本根据文件名将文件从一个目录移动到另一个目录
【发布时间】:2015-02-04 16:11:03
【问题描述】:

我正在尝试编写一个 sh 脚本,该脚本将在我的一个下载完成后运行。

它应该在 ~/Downloads 上查找特定文件名,并根据文件名将其移动到不同的目录。

即我已经下载了《欢乐合唱团》最后一集,文件名是:

glee_some_trash_files_always_have.mkv

应该移到

~/TVshows/Glee/

这是我能够做到的:

#!/bin/bash

if filename in ~/Downoads; then
result=
if filename = *glee*; then
result= mv $filename ~/TVshows/Glee/
else
if filename = *pokemon*; then
result= mv $filename ~/TVshows/pokemon/
endif
done

我的方法正确吗?请注意,我对 sh 很陌生。

提前致谢。

###############################################################################

编辑:这是我的脚本,希望其他人能发现它有用:

#!/bin/bash

cd "$HOME/Downloads"
# for filename in *; do
find . -type f | while IFS= read filename; do # Look for files in all ~/Download sub-dirs
  case "${filename,,*}" in  # this syntax emits the value in lowercase: ${var,,*}  (bash version 4)
     *.part) : ;; # Excludes *.part files from being moved
     move.sh) : ;;
#    *test*)            mv "$filename" "$HOME/TVshows/Glee/" ;; # Using move there is no need to {&& rm "$filename"}
     *test*)           scp "$filename" "imac@imac.local:/users/imac/Desktop/" && rm "$filename" ;;
     *american*dad*)   scp "$filename" "imac@imac.local:/users/imac/Movies/Series/American\ Dad/" && rm "$filename" ;;
     *) echo "Don't know where to put $filename" ;;
  esac
done

【问题讨论】:

    标签: bash shell


    【解决方案1】:

    这就是 shell 的 case 语句派上用场的地方:

    #!/bin/bash
    cd "$HOME/Downloads"
    for filename in *; do
      # this syntax emits the value in lowercase: ${var,,*}  (bash version 4)
      case "${filename,,*}" in
        glee*)    mv "$filename" "$HOME/TVshows/Glee/" ;;
        pokemon*) mv "$filename" "$HOME/TVshows/pokemon/" ;;
        *) echo "don't know where to put $filename";;
      esac
    done
    

    【讨论】:

    • 很棒且简单的解决方案!非常感谢!我添加了一些修改: scp /path/to/local/file username@hostname:/path/to/remote/file 我需要将文件移动到另一台本地计算机。 :D
    • @Keith Thompson:确实如此,我今天学到了很多,不幸的是我只能选择一个答案,而格伦的答案更完整。即使尝试了您建议的修改,我以前的脚本也无法正常工作。希望你不要生我的气:(
    • 我遇到了一个问题,@glenn jackman 的脚本效果很好,但我还需要排除 *.part 文件的移动。我怎样才能做到这一点?
    • @fedxc,在case语句中添加一个分支before "glee*": *.part) : ;;
    • @glennjackman 谢谢!现在几乎完美了。我还有几个问题,但我不确定我是否应该提出一个新问题。无论如何:1)如何防止已经复制的文件被再次复制? -或者- 文件复制后如何删除? 2) 有没有办法告诉脚本查看 ~/Downloads 及其所有子目录?先谢谢了。我稍后会发布我的完整脚本,以防其他人发现它有用。
    【解决方案2】:

    mv 命令可以一次移动多个文件。最后一个参数被视为目录名称。尾随/ 很重要;如果有一个匹配的文件名,并且目标目录不存在(比如说,因为你拼错了它),它会将它创建为一个文件。

    mv ~/Downloads/*glee* ~/TVshows/Glee/
    mv ~/Downloads/*pokemon* ~/TVshows/pokemon/
    

    【讨论】:

    • 谢谢!我不知道!
    【解决方案3】:

    这是我的序列排序脚本。

    #!/bin/bash
    
    PATH_FROM=/your/download/dir
    PATH_TO=/path/serial/directory
    
    cd $PATH_FROM
    ls -1 *{mkv,avi,srt,mp4} | sed -e 's/\.[s|S][0-9].*$//g' | uniq | while read -r serial
    do
        folder=$(echo $serial | tr A-Z a-z) folder=${folder/the./}
        folder=`echo ${folder//_/.}`
        folder=`echo ${folder//./ }`
    
        folder=( $folder )
        folder=`echo "${folder[@]^}"`
    
        ls -1 ${serial// /.}.* | sed -e 's/'$serial'\.[s|S]//g' | sed -e 's/\..*$//g' | uniq | while read -r s
        do
            season=s$(echo "$s" | sed -e 's/[e|E].*$//g' | sed -e 's/^0//g')
            mkdir -p "$PATH_TO/$folder/$season"
            mv -f $serial.?$s* "$PATH_TO/$folder/$season/"
            log=`date +"[%d/%m/%Y %X]"`
            echo $log" "$serial" success sync with "$PATH_TO"/"$folder"/"$season >> /path/to/logfiledir/log.txt
        done
    done
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-26
      • 1970-01-01
      • 1970-01-01
      • 2014-12-04
      相关资源
      最近更新 更多