Shell-Script
使用 xargs 輸入替換命令
我正在嘗試編寫一個簡單的命令,該命令將為特定目錄中的所有文件創建符號連結(是的,完全一樣,
lndir
但我不能使用它,所以我嘗試模仿它)。
find
我使用+嘗試了以下操作xargs
:find $(realpath ${FROM_DIR}) -maxdepth 1 -print0 | xargs -0 -I{} ln -sfn {} ${TO_DIR}/$(basename {})
但問題是 shell
$(basename {})
在執行該行之前替換了一次,而不是每個參數。將其編寫為循環如下所示:
for i in $(find $(realpath ${FROM_DIR}) -maxdepth 1) do ln -sfn $i ${TO_DIR}/$(basename $i) done
這有效,但速度相對較慢。我想知道這是否也可以使用
xargs
。
聽起來像你想要的:
ln -sf -- "$(realpath -- "$FROM_DIR")"/* "$TO_DIR/"
當最後一個參數是一個目錄時,
ln
, 喜歡cp
或創建指向該目錄內mv
具有相同基名的另一個參數的連結。或與
zsh
:ln -sf -- $FROM_DIR:P/* $TO_DIR/
如果
$FROM_DIR
無法確定 的真實路徑或在$FROM_DIR
.(添加
D
限定符還可以為隱藏文件創建符號連結)。
ln
或者,如果您出於某種原因確實需要為每個文件呼叫一次:for f ($FROM_DIR:P/*(ND)) ln -sfT -- $f $TO_DIR/$f:t
(注意
-n
和-T
是非標準擴展)。要使用 shell 命令替換 with
xargs
(或在這裡, withfind -exec
, usingxargs
將毫無意義),您需要它們來執行 shell: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)
)。你最好使用sh
’s${file##*/}
或zsh
$file:t
here ($FROM_DIR:P
forrealpath
)。在這裡,您只需要:
find "$(realpath -- "$FROM_DIR")" -mindepth 1 -maxdepth 1 \ -exec ln -sft "$TO_DIR" -- {} +
雖然(
-t
也是一個 GNU 擴展)。如果文件太多(在 中,您可以通過使用或載入模組以獲取 的內置版本來解決此問題),則該錯誤不受太多參數錯誤的影響。$TO_DIR``zsh``zargs``zsh/files``ln
有關您嘗試的其他問題,另請參閱這些問答: