1

私のルートフォルダの構造は次のようになります。

私の家族-休日
私の誕生日[15.11]
名前-名前[1]
Name1
Name2
..。

.infoここで、ファイルを含むすべてのフォルダーを別のディレクトリに移動する必要があります。

これが私のコードです:

#!/bin/sh

for folder in *
do
    echo $folder
    if [ -e "$folder/*.info" ]
    then
            echo $folder
            mv  $folder ./Finished
    fi
done

エコーはテスト専用です。エスケープされていない文字が名前に含まれているたびに、ifが失敗していることがわかりました。どうすればこれを修正できますか?

4

3 に答える 3

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

ターゲットディレクトリをスラッシュで終了することをお勧めします。そうすれば、何らかの理由でFinishedディレクトリが消えた場合、最初の$ folderの名前を黙ってFinishedに変更してから、他のすべての一致を最初の一致に移動するのではなく、エラーが発生します。

また、いずれかのがハイフンで始まるprintf場合に備えて、デバッグ出力の一部に使用していることにも注意してください。$folder

更新#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 ~$

あなたが本当に見つけたいのが「.infoで終わるファイル」であるなら、それ[[ -eは行く方法ではありません。私がこの答えにさらに取り組む前に、plsは確認します。:)

更新#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]$ 
于 2012-08-08T11:25:03.537 に答える
3

主な問題は、を使用できないことtest -e *.infoです。lsの出力を解析して、ファイルを確認できます。lsの解析には問題がありますが、多くの人がそうするよりもはるかに重要ではありません。ファイル名に改行を許可しない場合は、次のように機能するはずです。

#!/bin/sh

for dir in *; do
    if ls -f "$dir" | grep -q '\.info$'; then
        mv "$dir" ./Finished
    fi
done

foo.info\nbarに名前が付けられた単一のファイルがあるかのように名前が付けられたファイルを誤って識別するため、ファイル名に改行が埋め込まれていないことが重要であることに注意してくださいfoo.info。実際には、これが重大な問題になる可能性は低いです。これが問題である場合は、次のことはできますが、シェルを使用したくないでしょう。

#!/bin/sh

for dir in *; do
    for f in "$dir"/*; do
        case "$f" in 
            *.info) mv "$dir" ./Finished; break;;
        esac
    done
done
于 2012-08-08T16:15:00.147 に答える
-1

これを試して:

    PATH_TO_FOLDER="/YOUR_FOLDER"

    for f in `ls $PATH_TO_FOLDER`;
    do
        # Check filename

        if [ $(echo $f | grep -Ec ".info$") -ne 1 ]
        then
            echo "We don't care"
        else
            ## move the file
        fi
    done
于 2012-08-08T11:22:30.043 に答える