「mv」の可変空間処理

「mv」の可変空間処理

次のファイル/ディレクトリを含むディレクトリがあるとします。

google
apple
mozilla foundation   # a file with spaces
browsers

browsersだからファイルをディレクトリに移動したいと思います。私が書いたスクリプトは次のとおりです。

for d in $(ls); do
    if ! [ "$d" == "browsers" ]; then
        mv "$d" "browsers"
    fi
done

それから行きましたが、google得ました。applebrowsers

mv: cannot stat 'mozilla': No such file or directory
mv: cannot stat 'foundation': No such file or directory

明らかに問題は変数の空白です。この問題を処理する正しい方法は何ですか?

もちろん、これを行うには、よりエレガントな1行のコマンドが必要であると確信していますが、空白のある変数をどのように使用するかを知りたいです。

答え1

するいいえ使用した:

for d in $(ls)

代わりにこれを使用してください:

for d in *

これを使用する際の2つの問題は、$(ls)シェルが結果を$(ls)次のように適用することです。噴射そしてパス名拡張。あなたが思う限り、そうです噴射これが mozilla foundation原因とmozillaなりますfoundation

を使用しない理由の詳細については、$(ls)次を参照してください。「何してる$(ls *.txt)?」

ディレクトリに隠されていないファイルがない場合を考慮する必要がある場合(この場合はループ内でfor i in $(ls)1回のパスを実行するのではなく(*除く)、ループ内でパスを実行しないため、より良く見える場合があります)、一致しないグローブに拡張しないようにシェルに指示したいと思います。$ifor i in *zsh

  • zsh:for i in *(N)
  • ksh93:for i in ~(N)*
  • bash4.4+:(f() { local -; shopt -s nullglob; for i in *; ...; done; }; fこのオプションをローカルで使用することを強調表示します(デフォルトオプションと同様の動作nullglobについては、このオプションも参照してください))。failglobzsh
  • yash:(それからリセットします。私が知っている限り、ローカルスコープset -o nullglobオプションはありません)yash
  • 他のシェルでは、常に[ -e "$i" ] || [ -L "$i" ] || continueループに追加してファイルが存在することを確認できます。

答え2

ls結果を解析しない、John1024の答えに加えてfind

LC_ALL=C find . ! -name . -prune ! -name '.*' -type f -exec mv -t /path/to/dest {} +

(これはGNUfindオプションが使用され、globなど-tの隠しファイルをスキップし、非正規ファイルを除外すると仮定します。リストはソートされません(または逆)。名前がこれらで始まるすべてのファイルは正しくスキップする必要があります。有効な文字には含まれませんが、これはエラーメッセージの言語に影響します。ls*ls*LC_ALL=C.

関連情報