Bash脚本交换文件位置,具有相同名称的文件

问题描述 投票:1回答:1

我的Mac上的文件夹中有一堆.mov视频:

Documents/MyMovs
├── SubFolder01
│   ├── SubSubFolder01
│   │   ├── MyFile1.mov
│   │   ├── MyPdf.pdf
│   │   └── MyTxt.txt
│   └── SubSubFolder02
│       ├── MyFile2.mov
│       ├── MyPdf.pdf
│       └── MyTxt.txt
etc.

[使用HandBrake,我将它们全部转换为.mp4,但是HandBrake将它们全部都放入了Movies /

Movies
├── MyFile1.mp4
├── MyFile2.mp4
etc.

我想做的是交换文件,并得到完全相反的情况,所有我的mp4都存储在正确的位置(位于正确的位置)在Documents / MyMovs中,所有mov文件都在Movies /中,我最终可以删除它们。

最后我要:

Documents/MyMovs
    ├── SubFolder01
    │   ├── SubSubFolder01
    │   │   ├── MyFile1.mp4
    │   │   ├── MyPdf.pdf
    │   │   └── MyTxt.txt
    │   └── SubSubFolder02
    │       ├── MyFile2.mp4
    │       ├── MyPdf.pdf
    │       └── MyTxt.txt
    etc.

  Movies
    ├── MyFile1.mov
    ├── MyFile2.mov
    etc.

我设计了以下bash脚本来帮助我(尽管由于冠状病毒危机,我有时间手动完成此操作:]

#!/usr/local/bin/bash

MOV_DIR=$1
MP4_DIR=$2

declare -A FILES=( )

find $MOV_DIR -maxdepth 3 -name '*.mov' -print0 |
    while IFS= read -r -d '' line; do
        filename=$(basename "$line")
        extension="${filename##*.}"
        filename="${filename%.*}"
        path_to_file=$(dirname "$line")
        if [[ ! -v FILES[$filename] ]]; then
          FILES[$filename]="$path_to_file"
          #echo $FILES[$filename] prints something!
        fi
    done

#for k in "${!FILES[@]}"; do echo "$k - ${FILES[$k]}"; done  ## prints nothing!

find $MP4_DIR -maxdepth 3 -name '*.mp4' -print0 |
    while IFS= read -r -d '' line; do
        filename=$(basename "$line")
        extension="${filename##*.}"
        filename="${filename%.*}"
        path_to_file=$(dirname "$line")
        if [[ ! -z ${FILES["$filename"]} ]]; then
            mv "$path_to_file/$filename.mp4" "${FILES[$filename]}"
            mv "${FILES[$filename]}/filename.mov" "$path_to_file"
            #I would like to remove $filename from FILES as well but I don't know how
        fi
    done

为了简单起见,所有文件名都是唯一的并且彼此不同。

我将所有mov文件都放在了映射文件名中-> path_to_filename;例如MyFile1-> Documents / MyMovs / SubFolder01 / SubSubFolder01。这是第一个查找块。

其次,我找到了所有的mp4文件,并使用地图检索了正确的位置。

代码似乎不起作用,似乎该地图是第一个find命令的本地地图,之后不存在。有人知道为什么吗?我使用bash 5.0.16(1)-发行版。谢谢大家!

PS:我有一个完全不同但更好的解决方案,随时分享

bash dictionary
1个回答
0
投票

如果有一个文件,然后找到另一个

find Documents -maxdepth 4 -mindepth 3 -name '*.mov' -print0 |
while IFS= read -r -d '' mov; do
        # extract the filename without extension
        name=$(basename "$mov" .mov)
        # find exactly the same name in Movies but with mp4
        mp4="Movies/$name.mp4"
        if [[ ! -f "$mp4" ]]; then
                echo "ERROR: File $mp4 does not exists" >&2
                exit 2
        fi
        # switch mp4 with mov
        movdir=$(dirname "$mov")
        mp4dir=$(dirname "$mp4")
        echo mv -v "$mp4" "$movdir"
        echo mv -v "$mov" "$mp4dir"
done

使用以下目录/文件重新创建:

# find -type f
./Documents/MyMovs/Subfolder01/SubSubFolder01/MyFile1.mov
./Documents/MyMovs/Subfolder01/SubSubFolder02/MyFile2.mov
./Movies/MyFile1.mp4
./Movies/MyFile2.mp4

输出:

mv -v Movies/MyFile1.mp4 Documents/MyMovs/Subfolder01/SubSubFolder01
mv -v Documents/MyMovs/Subfolder01/SubSubFolder01/MyFile1.mov Movies
mv -v Movies/MyFile2.mp4 Documents/MyMovs/Subfolder01/SubSubFolder02
mv -v Documents/MyMovs/Subfolder01/SubSubFolder02/MyFile2.mov Movies

之后不存在。有人知道为什么吗?

因为|的右侧在子shell中运行。父外壳对子外壳环境一无所知。

$ echo | { a=1; echo a=$a; }
a=1
$ echo a=$a
a=
热门问题
推荐问题
最新问题