使用bash对文件夹进行排序

dem*_*ing 1 unix shell

我的根文件夹结构是这样的:

My Family - Holiday
My Birthday[15.11]
Name-Name[1]
Name1
Name2
...

现在,我希望包含.info文件的每个文件夹都移动到另一个目录.

这是我的代码:

#!/bin/sh

for folder in *
do
    echo $folder
    if [ -e "$folder/*.info" ]
    then
            echo $folder
            mv  $folder ./Finished
    fi
done
Run Code Online (Sandbox Code Playgroud)

回声仅用于测试.我发现每次非转义字符都在名称中if失败.我怎样才能解决这个问题?

gho*_*oti 6

Bash希望你引用你的变量.

#!/bin/bash

if [[ "$1" = "-v" ]]; then
    Verbose=true
    vopt="-v"
    shift
else
    Verbose=false
    vopt=""
fi

for folder in *; do
    $Verbose && printf "%s" "$folder"
    if [[ -e "$folder/*.info" ]]; then
            if mv "$vopt" "$folder" ./Finished/; then
                $Verbose && echo -n " ... done"
            fi
    fi
    $Verbose && echo ""
done
Run Code Online (Sandbox Code Playgroud)

请注意,使用斜杠结束目标目录是个好主意.这样,如果由于某种原因Finished目录消失,你将得到一个错误,而不是默默地将第一个$文件夹重命名为Finished,然后将所有其他匹配移动到第一个匹配.

另请注意,我正在使用printf某些调试输出,以防你$folder的一个s以连字符开头.

更新#1:您现在可以使用该-v选项控制调试.

更新#2:我刚刚意识到你正在检查*.info字面上的存在.注意:

ghoti@pc ~$ mkdir foo
ghoti@pc ~$ touch foo/\*.info
ghoti@pc ~$ ls -la foo
total 0
-rw-r--r--   1 ghoti  ghoti    0  8 Aug 07:45 *.info
drwxr-xr-x   3 ghoti  ghoti  102  8 Aug 07:45 .
drwx------+ 10 ghoti  ghoti  340  8 Aug 07:44 ..
ghoti@pc ~$ [[ -e "foo/*.info" ]] && echo yes
yes
ghoti@pc ~$ mv foo/\*.info foo/bar.info
ghoti@pc ~$ [[ -e "foo/*.info" ]] && echo yes
ghoti@pc ~$
Run Code Online (Sandbox Code Playgroud)

如果您真正想要找到的是"任何以.info结尾的文件",那么[[ -e就不是这样了.在我更多地研究这个答案之前请确认一下.:)

更新#3:

如果文件夹包含任何.info文件,这是一个可以移动文件夹的版本.请注意,这并没有用grep的输出ls.

[ghoti@pc ~/tmp1]$ cat doit 
#!/bin/bash

if [[ "$1" = "-v" ]]; then
    Verbose=true
    vopt="-v"
    shift
else
    Verbose=false
    vopt=""
fi

for folder in *; do

    infofile="$(
        if [[ -d "$folder" ]]; then
            cd "$folder"
            for file in *.info; do
              if [[ -f "$file" ]]; then
                  echo "$file"
                  break
              fi
            done
        fi
    )"

    if [[ -f "$folder/$infofile" ]]; then
        mv "$vopt" "$folder" ./Finished/
    elif $Verbose; then
        printf "%s ... skipped\n" "$folder"
    fi

done
[ghoti@pc ~/tmp1]$ find . -print
.
./doit
./baz
./foo
./foo/bar.info
./Finished
[ghoti@pc ~/tmp1]$ ./doit -v
Finished ... skipped
baz ... skipped
doit ... skipped
foo -> ./Finished/foo
[ghoti@pc ~/tmp1]$ 
Run Code Online (Sandbox Code Playgroud)

  • +1确实.养成引用所有变量的习惯 (2认同)