0

I need use in find results full path and dir name. This not work:

find ./1cv8 -maxdepth 1 -type d -wholename "./1cv8/*" -exec bash -c 'echo vrunner -src "{}" -o ./builds/"${basename "{}"}"' \;

error:

bash: ${basename "./1cv8/common"}: bad substitution
bash: ${basename "./1cv8/conf"}: bad substitution
bash: ${basename "./1cv8/x86_64"}: bad substitution

Please help

1
  • 1
    Do you mean $(basename "{}")?
    – Bodo
    Commented Oct 2, 2023 at 10:21

2 Answers 2

2

The immediate error is from using ${...} in place of a command substitution, $(...). However, you also don't generally want to inject the pathname into the in-line shell script using {}, but instead to pass it as an argument to bash -c:

find ./1cv8 -maxdepth 1 -type d -exec bash -c '
    echo vrunner -src "$1" \
        -o "./builds/$(basename "$1")"
    ' bash {} \;

or, for a slight speed increase from not starting a new shell for each match,

find ./1cv8 -maxdepth 1 -type d -exec bash -c '
    for pathname do
        echo vrunner -src "$pathname" \
            -o "./builds/$(basename "$pathname")"
    done' bash {} +

This way, you will have no issues with names containing quotes or things that the shell will interpret as expansions, redirections, pipes etc., as the pathname is no longer injected and used as shell code.

Note that I deleted your -wholename test as it would always be true.

See also:


In the bash shell, since you don't actually use find to locate the directories in any other directory than in the top-level one:

shopt -s nullglob dotglob

for pathname in ./1cv8/*; do
    if [ ! -d "$pathname" ] || [ -L "$pathname" ]; then
        # skip oven non-directories and symbolic links
        continue
    fi

    echo vrunner -src "$pathname" \
        -o "./builds/$(basename "$pathname")"
done
0
1

Just switch to zsh and do:

for dir (1cv8/*(ND/)) vrunner -src $dir -o builds/$dir:t

with:

  • (ND/) are glob qualifiers with:
    • N: nullglob: does not report an error if there's no match
    • D: include hidden files (like find does by default), you'd likely want to skip that unless you do want to process hidden dirs.
    • /: restrict the glob expansion to files of type directory (like find's -type d).
  • $dir:t: the tail (basename) of the directory like in csh or vim.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .