Reputation: 193
I have a directory $dir
that contains .txt.xy
files and subdirectories with .txt.xy
files. I try to iterate over each file and pass the whole path as well as the path without $dir
as argument to a program like this:
dir="/path/to/"
suffix=".xy"
find "$dir" -name "*.txt.xy" -print0 | xargs -0 -I {} sh -c 'program "$1" |
subprogram filename="$2"' _ {} "$(echo {} | sed -e "s#^${dir}##" -e "s#${suffix}\$##")"
$1
shold be the full path (e.g. /path/to/subdir/file.txt.xy
)$2
should be the full path without $dir
and $suffix
(e.g. subdir/file.txt
)$1
is the propper full path but $2
is also the full path as if the pipe in $(...)
is never executed. What am I missing here?
Upvotes: 1
Views: 115
Reputation: 189387
Your attempt seems rather roundabout. It sounds like you are looking for
find /path/to -name "*.txt.xy" -exec sh -c '
for f; do
g=${f##*/}
program "$f" | subprogram filename="${g%.xy}"
done' _ {} +
If you really need your parameters to be in variables, maybe pass in the suffix as $0
which isn't used for anything useful here anyway. It's a bit obscure, but helps avoid the mess you had with double quotes.
find /path/to -name "*.txt.xy" -exec sh -c '
for f; do
g=${f##*/}
program "$f" | subprogram filename="${g%"$0"}"
done' ".xy" {} +
The above simply trims g
to the basename which I guess on closer reading you don't want. So pass /path/to
in $0
instead, and hardcode .xy inside:
find /path/to -name "*.txt.xy" -exec sh -c '
for f; do
g=${f#"$0"/}
program "$f" | subprogram filename="${g%.xy}"
done' "/path/to" {} +
or if you really need both to be command-line parameters,
dir="/path/to"
suffix=".xy"
find "$dir" -name "*.txt$suffix" -exec sh -c '
suffix=$1
shift
for f; do
g=${f#"$0"/}
program "$f" | subprogram filename="${g%"$suffix"}"
done' "$dir" "$suffix" {} +
Upvotes: 2
Reputation: 85580
One reason for the failure, is that the command substitution with xargs
under double quotes is expanded by the shell even before the former is executed. One way to avoid that would be to do the whole substitution inside the sub-shell created by sh -c
as
find "$dir" -name "*.txt.xy" -print0 |
xargs -0 -I {} sh -c '
f="{}"
g="$(echo "$f" | sed -e 's|"'^"${dir}"'"||' -e 's|"'\\"${suffix}"$'"||' )"
program "$f" | subprogram filename="$g"
'
Upvotes: 1