GNU find:在-exec中獲取絕對和相對路徑
我有一個
echo
要執行的命令(不是!),它採用絕對路徑和相對路徑。我如何得到這兩個論點?
試圖:
d=/tmp/foo; find "$d" -type f -exec bash -c 'echo d=${1:${#d}} 1="${1%/*}"' bash {} \;
(我喜歡 GNU find 因為它是遞歸的,可以按文件限制,可以按文件名過濾,並且不會產生過多的 shell)
期待:
mkdir -p /tmp/foo/bar/can/haz; touch /tmp/foo/bar/can/haz/bzr.txt # cmd is run, output is: d=bar/can/haz 1=/tmp/foo/bar/can/haz
Export
d
,那麼它將在您的bash
內聯腳本中可用。你也根本不需要bash
這裡。你的(希望更苗條/更快)sh
也會這樣做。此外,您不需要為每個文件執行一個 shell。您可以使用變體將更多文件傳遞給您的內聯腳本-exec cmd {} +
:d=/tmp/foo export d find "$d" -type f -exec sh -c ' for file do relative=${file#"$d/"} dir=${file%/*} relative_dir=${relative%/*} relative_dir=${relative_dir:-.} printf "%10s: %s\n" full "$file" \ relative "$relative" \ dir "$dir" \ reldir "$relative_dir" done' sh {} +
這使:
full: /tmp/foo/bar/can/haz/bzr.txt relative: bar/can/haz/bzr.txt dir: /tmp/foo/bar/can/haz reldir: bar/can/haz
但是,如果您只需要相對路徑,那麼這樣做可能會更簡單:
(cd -P -- "$d" && find . -exec sh -c 'for file do...' sh {} +)
這也會使傳遞給
sh
更短的命令參數,因此允許find
傳遞更多參數給sh
.請注意,您的
find
命令和我的命令中都沒有特定於 GNU 的內容。這應該適用於任何符合 POSIX 的find
實現,而不僅僅是 GNU。您的問題中唯一的非 POSIX 部分顯然是 Korn shell 運算符,而不是bash
POSIX 。${1:offset}``sh
對於允許您指定文件類型的遞歸文件查找,另請參見
zsh
:(cd -P -- "$d" && for file (**/*(ND.)) { dir=$file:h printf '%10s: %s\n' relative $file reldir $dir })
上面,
.
is 相當於find
’s-type f
(僅正常文件),而D
is 也包括隱藏的文件find
。作為旁注,在一般情況下:
c=$a$b; d=${c:${#a}} [ "$b" = "$d" ] && echo yes
不保證輸出“是”,因為
${#var}
and${var:offset}
運算符使用字元,而不是字節。例如,在 UTF-8 語言環境中,它不會輸出帶有這些值的 yes
a
和b
:a=$'St\xc3' b=$'\xa9phane'
有了這些,
$c
將包含我的名字 (Stéphane
)$a
包含該é
字元$b
的一半,另一半${#a}
將是3
(2 個字元和 1 個字節不構成有效字元,但仍被計算在內)。
$d
會的,phane
不會$'\xa9phane'
的。但在特定情況下
d=$a/$b
,應該沒問題,因為系統語言環境中通常可用的字元集都不會包含除/
包含/
.