basenameでfind -execを使用するときにディレクトリにスペースを入れるにはどうすればよいですか?

basenameでfind -execを使用するときにディレクトリにスペースを入れるにはどうすればよいですか?

特定のパスですべてのディレクトリを探し、そのディレクトリ内の別の場所にある同じ名前のディレクトリへのソフトリンクを作成しようとしています。多くのディレクトリには名前にスペースがあります。次のコードを一緒にまとめてみると、空白がない限り正しく動作するようです。

find /some/path/* -maxdepth 0 -exec sh -c "ln -s /some/other/path/"'$(basename {})'" {}" \;

スペースを処理するにはどうすればよいですか?通常、私のディレクトリ名にはこれらのミラーディレクトリはありませんが、これらのミラーディレクトリは私のWindows PCにあり、その中にスペースを使用します。どんな助けでも大変感謝します!

編集する

cuonglmとGillesの主張に対する答え:

  • コマンド引数の順序には何の問題もありませんが、ln -s説明の中で私が望むものが何であるかは明らかではありません。各ディレクトリに/some/path/シンボリックリンクを作成したい存在するこのディレクトリは、で同じ名前のディレクトリを指します/some/other/path//some/other/path/はい、私がこれをしたいのは、インクルードにディレクトリのサブセットがあり、各ディレクトリのサブセットからフルセットへのリンクが欲しいからです。source/some/path/destination/some/path//some/other/path/

  • パスにはディレクトリがあまりありませんが、それを妨げないのは無意味な欠陥であることに同意します。

  • 未使用の理由-type dは、指定されたパスにディレクトリだけがあり、ファイルがないためです。

答え1

コマンドにはいくつかの問題があります。

  • /some/path/*以下のディレクトリが多すぎると、パラメータリストが長すぎます。エラーが発生する可能性があります。/some/path

  • ディレクトリやファイルをフィルタリングしません。

  • インラインスクリプトを使用しているため非常に非効率的ですがsh -c-exec ... {} \;

  • lnパラメータの位置が間違っていると、ln -s source desttoの代わりにto toとしてシンボリックリンクが生成されます。sourcedestdestsource


POSIX 方式でこれを行うことができます。

find /some/path ! -path /some/path -prune -type d -exec sh -c '
  for f do
    ln -s "$f" /some/other/path/"${f##*/}"
  done
' sh {} +

またはあなたがfindサポートしている場合-maxdepth

find /some/path -maxdepth 1 -type d -exec sh -c '...' sh {} +

答え2

まず、常に{}別々のパラメータとして使用されますfind -exec …。一部(完全ではない)バージョンで動作するバージョンを使用してください。ただし、スペースなどの「異常な」文字を含むファイル名を処理することは不可能です。 (正確にどの文字が問題を引き起こすかは、使用している特定の場所によって異なります。)別のパラメータとして渡されます。次の最初のパラメータはです。stuff{}morestufffind'"{}{}sh -c CODE$0変数拡張の二重引用符を忘れないでください。

find … -exec sh -c 'ln -s /some/other/path/$(basename "$0") "$0"' {} \;

(全体的に一重引用符を使用して引用を簡素化しました。)

コマンドに 1 つ以上の問題があります。findシンボリックリンクがすでに存在する返された場所にシンボリックリンクを作成しようとしています。下にシンボリックリンクを作成したいようです/some/other/path。この場合、パラメータを置き換える必要がありますln(たとえば、およびmvcp既存のファイルの最初、ターゲットの最後など)。

find /some/path/* -maxdepth 0 -exec sh -c 'ln -s "$0" /some/other/path/$(basename "$0")' {} \; 

basenamesh代わりに、シェル文字列操作構造を使用して呼び出しを一度にバッチ処理すると、作業を高速化できます。

find /some/path/* -maxdepth 0 -exec sh -c '
  for x do
    ln -s "$x" /some/other/path/${x##*/};
  done' {} +

これが実際のfindコマンドであれば、findここでは役に立ちません。ポイントは、findサブディレクトリに再帰することです。非再帰的なルックアップは、時々フィルタを利用するのに役立ちます(たとえば、特定の種類のファイルまたは特定の期間内に変更されたファイルに対してのみ機能します)。しかし、findフィルタリングのない非再帰は意味がありません。

for x in /some/path/*; do
  ln -s "$x" "/some/other/path/${x##*/}";
done' {} +

または

cd /some/path
for x in *; do
  ln -s "$PWD/$x" "/some/other/path/$x";
done' {} +

または扱いにくい:

autoload -U zmv
alias zln='zmv -L'
zln -s '/some/path/*' '/some/other/path/$f:t'

関連情報