
特定のパスですべてのディレクトリを探し、そのディレクトリ内の別の場所にある同じ名前のディレクトリへのソフトリンクを作成しようとしています。多くのディレクトリには名前にスペースがあります。次のコードを一緒にまとめてみると、空白がない限り正しく動作するようです。
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 dest
toの代わりにto toとしてシンボリックリンクが生成されます。source
dest
dest
source
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{}morestuff
find
'
"
{}
{}
sh -c CODE
$0
変数拡張の二重引用符を忘れないでください。。
find … -exec sh -c 'ln -s /some/other/path/$(basename "$0") "$0"' {} \;
(全体的に一重引用符を使用して引用を簡素化しました。)
コマンドに 1 つ以上の問題があります。find
シンボリックリンクがすでに存在する返された場所にシンボリックリンクを作成しようとしています。下にシンボリックリンクを作成したいようです/some/other/path
。この場合、パラメータを置き換える必要がありますln
(たとえば、およびmv
、cp
既存のファイルの最初、ターゲットの最後など)。
find /some/path/* -maxdepth 0 -exec sh -c 'ln -s "$0" /some/other/path/$(basename "$0")' {} \;
basename
sh
代わりに、シェル文字列操作構造を使用して呼び出しを一度にバッチ処理すると、作業を高速化できます。
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'