Exportar d
, depois estará disponível no seu script bash
inline. Você também não precisa de bash
aqui. Seu (espero que mais magro / mais rápido) sh
também funcionaria. Além disso, você não precisa executar um shell por arquivo. Você pode enviar mais arquivos para seu script in-line com a variante -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 {} +
O que dá:
full: /tmp/foo/bar/can/haz/bzr.txt
relative: bar/can/haz/bzr.txt
dir: /tmp/foo/bar/can/haz
reldir: bar/can/haz
Mas se você precisar apenas do caminho relativo, pode ser mais simples fazer isso:
(cd -P -- "$d" && find . -exec sh -c 'for file do...' sh {} +)
Isso também faria com que os argumentos de comando passassem para sh
mais curto, então permitiria que find
passasse mais argumentos para sh
.
Note que não há nada específico para o GNU no seu comando find
nem no meu. Isso deve funcionar em qualquer implementação find
compatível com POSIX, não apenas na GNU. A única parte não POSIX em sua pergunta era obviamente bash
e o operador ${1:offset}
que é um operador de shell Korn, não em POSIX sh
.
Para uma pesquisa de arquivos recursiva que permite especificar o tipo de arquivo, consulte também zsh
:
(cd -P -- "$d" &&
for file (**/*(ND.)) {
dir=$file:h
printf '%10s: %s\n' relative $file reldir $dir
})
Acima, o .
é equivalente a find
-type f
(somente arquivos regulares), enquanto D
também inclui os ocultos, como find
.
Como uma nota secundária, no caso geral:
c=$a$b; d=${c:${#a}}
[ "$b" = "$d" ] && echo yes
Não é garantido a saída "sim", porque os operadores ${#var}
e ${var:offset}
trabalham com caracteres , não bytes .
Por exemplo, em uma localidade UTF-8, ela não emitirá "sim" com esses valores de a
e b
:
a=$'St\xc3' b=$'\xa9phane'
Com esses, $c
conteria meu primeiro nome ( Stéphane
) $a
contém metade desse é
caractere e $b
a outra metade, ${#a}
seria 3
(2 caracteres e 1 byte não formando um caracter válido, mas ainda é contado).
Então $d
seria phane
, não $'\xa9phane'
.
No caso específico de d=$a/$b
, ele deve estar OK, já que nenhum conjunto de caracteres geralmente disponível em localidades do sistema teria um caractere diferente de /
que contém a codificação de /
.