コマンド置換のためのxargs入力の使用

コマンド置換のためのxargs入力の使用

特定のディレクトリ内のすべてのファイルへのシンボリックリンクを生成する簡単なコマンドを作成しようとしています(はい、まったく同じですが、動作させることができず、模倣しようとlndirしています)。

find+を使って次のことを試しましたxargs

find $(realpath ${FROM_DIR}) -maxdepth 1 -print0 | xargs -0 -I{} ln -sfn {} ${TO_DIR}/$(basename {})

しかし、問題は、シェルが $(basename {})各パラメータに対してではなく、行を実行する前に一度置き換えられることです。

次のようにループで作成します。

for i in $(find $(realpath ${FROM_DIR}) -maxdepth 1)
do
    ln -sfn $i ${TO_DIR}/$(basename $i)
done

これはうまくいきますが、比較的遅いです。xargsを使用してもこれを行うことができるかどうか疑問に思います。

答え1

あなたがしたいと思います:

ln -sf -- "$(realpath -- "$FROM_DIR")"/* "$TO_DIR/"

最後の引数がディレクトリの場合は、同じ基本名を持つ別の引数へのリンクを好きまたは作成lnしますcpmv~へそのディレクトリ。

または以下を使用してzsh

ln -sf -- $FROM_DIR:P/* $TO_DIR/

実際のパスを確認できないか、$FROM_DIRファイルを$FROM_DIR

D修飾子を追加すると、隠しファイルへのシンボリックリンクも生成されます)。

または何らかの理由でlnファイルごとに1回呼び出す必要がある場合:

for f ($FROM_DIR:P/*(ND)) ln -sfT -- $f $TO_DIR/$f:t

-nおよび-Tは非標準拡張です。)

xargswith(またはここではwith find -exec、usingは意味がありません)に置き換えるシェルコマンドを使用するには、xargsシェルを実行するために必要です。

TO_DIR=$TO_DIR find "$(realpath -- "$FROM_DIR")" -mindepth 1 -maxdepth 1 \
  -exec sh -c '
    for file do
      ln -sfn -- "$file" "$TO_DIR/$(basename -- "$file")"
    done' sh {} +

ただし、コマンド置換は末尾の改行をすべて削除するので、任意のファイルのコマンド置換には使用できないことに注意してくださいbasename(ここでも同じ問題$(realpath))。ここでは、または(for)shを使用することをお勧めします。${file##*/}zsh $file:t$FROM_DIR:Prealpath

これには次のものが必要です。

find "$(realpath -- "$FROM_DIR")" -mindepth 1 -maxdepth 1 \
  -exec ln -sft "$TO_DIR" -- {} +

しかし(-tGNU拡張も可能)。それは影響を受けません。あまりにも議論するにファイルが多すぎると、エラーが発生する可能性があります$TO_DIR(このモジュールは、zsh組み込みバージョンを取得するためにモジュールを使用またはロードすることで解決できます)。zargszsh/filesln

他の質問については、次のQ&Aをご覧ください。

関連情報