3

ファイルの名前を変更するコードを使用していたところ、非常に興味深い問題が発生しました。Mac OSX Lion 10.7.5 を実行しているコンピュータでは機能しましたが、Mac OSX 10.6.8 Snow Leopard では機能しませんでした。

コードは次のとおりです。

for i in *; do mv $i `echo $i | sed 's/..//'`; done

私が得たエラーは次のとおりです。

usage: mv [-f | -i | -n] [-v] source target
   mv [-f | -i | -n] [-v] source ... directory

formv がループしていない場合は正常に動作しているため、非常に奇妙です...

誰でもそれを機能させるために何をすべきか知っていますか?

4

2 に答える 2

3

bash文字列置換を使用する必要があります。

for i in *; do mv $i ${i/??/}; done

また

for i in *; do mv $i ${i#??}; done
于 2013-06-14T04:18:09.017 に答える
2

スペース (または特定の他のシェル メタ文字) を含むファイルがある場合は、すべての変数参照を二重引用符で囲むことが重要です。それ以外の場合、たとえば がある場合i="File Name.txt"、次のようなコマンドを実行するmv File Name.txt le Name.txtと、2 つだけでなく 4 つのファイル名を指定していると見なされます。もう 1 つの標準的な間違い (これは作成していません) はfor file in $(ls)、スペースで混乱する の使用です。名前が変数に入る前に。

また、短いファイル名と名前の競合についても少し心配です。短いファイル名がないと思っていても、dotglob シェル オプションが設定されていると、疑似ファイルの名前を "." に変更しようとすることになります。と「..」、まったくうまくいきません。また、たとえば「abcdefg」と「cdefg」という名前のファイルがある場合、スクリプトは最初の名前を 2 番目の名前に変更し (2 番目の名前を黙って消去します)、次にその名前「efg」に変更します。

したがって、これが私の提案された書き直しです(ファイル名を短縮するための@TrueYの提案も使用しています):

for i in *; do
    if [ ${#i} -le 2 ]; then
        echo "$i: not renamed (too short)" >&2
    elif [ -e "${i:2}" ]; then
        echo "$i: not renamed (${i:2} already exists)" >&2
    else
        mv "$i" "${i:2}"
    fi
done
于 2013-06-14T14:55:45.400 に答える