Eu tenho um comando (não echo
!) Que desejo executar, que usa um caminho absoluto e um caminho relativo.
Como obtenho esses dois argumentos?
Tentar:
d=/tmp/foo;
find "$d" -type f -exec bash -c 'echo d=${1:${#d}} 1="${1%/*}"' bash {} \;
(Eu gosto do GNU find porque é recursivo, pode restringir por arquivo, pode filtrar por nome de arquivo e não gera shells excessivos)
Expectativa:
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
, ele estará disponível em seubash
script embutido. Você também não precisabash
de nada aqui. O seu (esperançosamente mais magro/rápido)sh
também funcionaria. Além disso, você não precisa executar um shell por arquivo. Você pode passar mais arquivos para seu script embutido com a-exec cmd {} +
variante:Que dá:
Mas se você precisar apenas do caminho relativo, pode ser mais simples fazer apenas:
Isso também tornaria os argumentos de comando passados para
sh
mais curtos, permitindofind
passar mais argumentos parash
.Observe que não há nada específico do GNU em seu
find
comando nem no meu. Isso deve funcionar em qualquer implementação compatível com POSIXfind
, não apenas na GNU. A única parte não-POSIX em sua pergunta foi obviamentebash
e o${1:offset}
operador que é um operador de shell Korn, não em POSIXsh
.Para uma pesquisa de arquivo recursiva que permite especificar o tipo de arquivo, consulte também
zsh
:Acima, o
.
é o equivalente afind
's-type f
(somente arquivos regulares), enquantoD
também inclui os ocultos comofind
does.Como nota lateral, no caso geral:
Não é garantido que a saída seja "sim", porque os operadores
${#var}
e trabalham com caracteres , não com bytes .${var:offset}
Por exemplo, em uma localidade UTF-8, não resultaria sim com esses valores de
a
eb
:Com esses,
$c
conteria meu primeiro nome (Stéphane
) conteria$a
metade desseé
caractere e$b
a outra metade,${#a}
seria3
(2 caracteres e 1 byte não formando um caractere válido, mas ainda contado).Assim
$d
seriaphane
, não$'\xa9phane'
.No caso específico de
d=$a/$b
, porém, deve estar OK, pois nenhum dos conjuntos de caracteres geralmente disponíveis em localidades do sistema teria um caractere diferente/
daquele que contém a codificação de/
.