find exec '{}' not available after >
up vote
6
down vote
favorite
Exec allows us to either pass all arguments at once with {} +
or to pass them one by one with {} ;
Now let's say I want to rename all jpeg, no problem doing this:
find . ( -name '*.jpg' -o -name '*.jpeg' ) -exec mv '{}' '{}'.new ;
But if I need to redirect output, '{}'
isn't accessible after redirection.
find . ( -name '*.jpg' -o -name '*.jpeg' ) -exec cjpeg -quality 80 '{}' > optimized_'{}' ;
This wouldn't work. I'd have to use a for loop, storing find's output into a variable before using it. Let's admit it, it's cumbersome.
for f in `find . ( -name '*.jpg' -o -name '*.jpeg' )`; do cjpeg -quality 80 $f > optimized_$f; done;
So is there a better way?
bash find
|
show 4 more comments
up vote
6
down vote
favorite
Exec allows us to either pass all arguments at once with {} +
or to pass them one by one with {} ;
Now let's say I want to rename all jpeg, no problem doing this:
find . ( -name '*.jpg' -o -name '*.jpeg' ) -exec mv '{}' '{}'.new ;
But if I need to redirect output, '{}'
isn't accessible after redirection.
find . ( -name '*.jpg' -o -name '*.jpeg' ) -exec cjpeg -quality 80 '{}' > optimized_'{}' ;
This wouldn't work. I'd have to use a for loop, storing find's output into a variable before using it. Let's admit it, it's cumbersome.
for f in `find . ( -name '*.jpg' -o -name '*.jpeg' )`; do cjpeg -quality 80 $f > optimized_$f; done;
So is there a better way?
bash find
Isn't there a>
missing in the third code sample?
– choroba
2 days ago
1
Even your first line is nonstandard and thus non-portable. Try to avoid command lines where{}
appears in a longer strings as such strings are typically not expanded.
– schily
2 days ago
That first example does not do what you say.
– ctrl-alt-delor
2 days ago
1
You have fixed your question: I would no-longer change it.
– ctrl-alt-delor
2 days ago
1
For what it's worth, the primary reason that your redirection does not work as you wanted is that it is handled by the shell from which you launchfind
, once, and applied to thefind
command itself. The{}
has no special meaning in that context. The redirection is not an argument tofind
, and it certainly is not part of the-exec
clause.
– John Bollinger
2 days ago
|
show 4 more comments
up vote
6
down vote
favorite
up vote
6
down vote
favorite
Exec allows us to either pass all arguments at once with {} +
or to pass them one by one with {} ;
Now let's say I want to rename all jpeg, no problem doing this:
find . ( -name '*.jpg' -o -name '*.jpeg' ) -exec mv '{}' '{}'.new ;
But if I need to redirect output, '{}'
isn't accessible after redirection.
find . ( -name '*.jpg' -o -name '*.jpeg' ) -exec cjpeg -quality 80 '{}' > optimized_'{}' ;
This wouldn't work. I'd have to use a for loop, storing find's output into a variable before using it. Let's admit it, it's cumbersome.
for f in `find . ( -name '*.jpg' -o -name '*.jpeg' )`; do cjpeg -quality 80 $f > optimized_$f; done;
So is there a better way?
bash find
Exec allows us to either pass all arguments at once with {} +
or to pass them one by one with {} ;
Now let's say I want to rename all jpeg, no problem doing this:
find . ( -name '*.jpg' -o -name '*.jpeg' ) -exec mv '{}' '{}'.new ;
But if I need to redirect output, '{}'
isn't accessible after redirection.
find . ( -name '*.jpg' -o -name '*.jpeg' ) -exec cjpeg -quality 80 '{}' > optimized_'{}' ;
This wouldn't work. I'd have to use a for loop, storing find's output into a variable before using it. Let's admit it, it's cumbersome.
for f in `find . ( -name '*.jpg' -o -name '*.jpeg' )`; do cjpeg -quality 80 $f > optimized_$f; done;
So is there a better way?
bash find
bash find
edited 2 days ago
asked 2 days ago
Buzut
1335
1335
Isn't there a>
missing in the third code sample?
– choroba
2 days ago
1
Even your first line is nonstandard and thus non-portable. Try to avoid command lines where{}
appears in a longer strings as such strings are typically not expanded.
– schily
2 days ago
That first example does not do what you say.
– ctrl-alt-delor
2 days ago
1
You have fixed your question: I would no-longer change it.
– ctrl-alt-delor
2 days ago
1
For what it's worth, the primary reason that your redirection does not work as you wanted is that it is handled by the shell from which you launchfind
, once, and applied to thefind
command itself. The{}
has no special meaning in that context. The redirection is not an argument tofind
, and it certainly is not part of the-exec
clause.
– John Bollinger
2 days ago
|
show 4 more comments
Isn't there a>
missing in the third code sample?
– choroba
2 days ago
1
Even your first line is nonstandard and thus non-portable. Try to avoid command lines where{}
appears in a longer strings as such strings are typically not expanded.
– schily
2 days ago
That first example does not do what you say.
– ctrl-alt-delor
2 days ago
1
You have fixed your question: I would no-longer change it.
– ctrl-alt-delor
2 days ago
1
For what it's worth, the primary reason that your redirection does not work as you wanted is that it is handled by the shell from which you launchfind
, once, and applied to thefind
command itself. The{}
has no special meaning in that context. The redirection is not an argument tofind
, and it certainly is not part of the-exec
clause.
– John Bollinger
2 days ago
Isn't there a
>
missing in the third code sample?– choroba
2 days ago
Isn't there a
>
missing in the third code sample?– choroba
2 days ago
1
1
Even your first line is nonstandard and thus non-portable. Try to avoid command lines where
{}
appears in a longer strings as such strings are typically not expanded.– schily
2 days ago
Even your first line is nonstandard and thus non-portable. Try to avoid command lines where
{}
appears in a longer strings as such strings are typically not expanded.– schily
2 days ago
That first example does not do what you say.
– ctrl-alt-delor
2 days ago
That first example does not do what you say.
– ctrl-alt-delor
2 days ago
1
1
You have fixed your question: I would no-longer change it.
– ctrl-alt-delor
2 days ago
You have fixed your question: I would no-longer change it.
– ctrl-alt-delor
2 days ago
1
1
For what it's worth, the primary reason that your redirection does not work as you wanted is that it is handled by the shell from which you launch
find
, once, and applied to the find
command itself. The {}
has no special meaning in that context. The redirection is not an argument to find
, and it certainly is not part of the -exec
clause.– John Bollinger
2 days ago
For what it's worth, the primary reason that your redirection does not work as you wanted is that it is handled by the shell from which you launch
find
, once, and applied to the find
command itself. The {}
has no special meaning in that context. The redirection is not an argument to find
, and it certainly is not part of the -exec
clause.– John Bollinger
2 days ago
|
show 4 more comments
5 Answers
5
active
oldest
votes
up vote
11
down vote
accepted
You could use bash -c
within the find -exec
command and use the positional parameter with the bash command:
find . ( -name '*.jpg' -o -name '*.jpeg' ) -exec bash -c 'cjpeg -quality 80 "$1" > "$(dirname "$1")/optimized_$(basename "$1")"' sh {} ;
That way {}
is provided with $1
.
The sh
before the {}
tells the inner shell its "name", the string used here is used in e.g. error messages. This is discussed more in this answer on stackoverflow.
add a comment |
up vote
8
down vote
You have an answer(https://unix.stackexchange.com/a/481687/4778), but here is why.
The redirection >
, and also pipes |
, and $
expansion, are all done by the shell before the command is executed. Therefore stdout is redirected to optimized_{}
, before find
is started.
add a comment |
up vote
3
down vote
The redirection needs to be quoted to avoid that the present shell interprets it.
But quoting it will also avoid the output of the command to be redirected.
The known solution to this is to call a shell:
find . -name '*.jpg' -exec sh -c 'echo "$1" >"$1".new' called_shell '{}' ;
In this case, the redirection (>
) is quoted on the present shell and works correctly inside the called shell. The called_shell
is used as the $0
parameter (the name) of the child shell (sh
).
That works well if a suffix is added the name of the file, but not if you use a prefix. For a prefix to work you need both to remove the ./
that find prepend to filenames with ${1#./}
and to use the -execdir
option.
You may (or may not) want to use the -iname
option so that files named *.JPG
or *.JpG
or other variations are also included.
find . ( -iname '*.jpg' -o -iname '*.jpeg' ) -execdir sh -c '
cjpeg -quality 80 "$1" > optimized_"${1#./}"
' called_shell '{}' ;
And, you may (or may not) also want to call the shell once per directory instead of once per file by adding a loop (for f do … ; done
) and a +
at the end:
find . ( -iname '*.jpg' -o -iname '*.jpeg' ) -execdir sh -c '
for f; do cjpeg -quality 80 "$f" > optimized_"${f#./}"; done
' called_shell '{}' +
And, finally, as cjpeg
is able to directly write to a file, the redirection could be avoided as:
find . ( -iname '*.jpg' -o -iname '*.jpeg' ) -execdir sh -c '
for f; do cjpeg -quality 80 "$f" -outfile optimized_"${f#./}"; done
' called_shell '{}' +
add a comment |
up vote
3
down vote
cjpeg
has an option that lets you write to a named file, rather than standard output. If your version of find
supports the -execdir
option, you can take advantage of that to make the redirection unnecessary.
find . ( -name '*.jpg' -o -name '*.jpeg' )
-execdir cjpeg -quality 80 -outfile optimized_'{}' '{}' ;
Note: this actually assumes the BSD version of find
, which appears to strip the leading ./
from the file name when exanding to {}
. (Or conversely, GNU find
adds ./
to the name. There's no standard to say which behavior is "right".)
If yourfind
supports-execdir
, you can use that instead of-exec
. It causes the command to run in the directory where the file was found, and{}
will becomeaa.jpg
instead of./t2/aa.jpg
.
– chepner
2 days ago
Still in error:cjpeg: can't open optimized_./aa.jpg
.
– Isaac
2 days ago
Hm, that appears to be a difference between GNUfind
and BSDfind
. (The perils of using non-standard extensions.)
– chepner
2 days ago
A filename without a leading./
seems to be more prone to errors. A reasonable solution is proposed in this answer.
– Isaac
2 days ago
add a comment |
up vote
1
down vote
Create a script cjq80:
#!/bin/bash
cjpeg -quality 80 "$1" > "${1%/*}"/optimized_"${1##*/}"
Make it executable
chmod u+x cjq80
And use it in -exec:
find . ( -name '*.jpg' -o -name '*.jpeg' ) -exec cjq80 '{}' ;
I had though about this, but it's not very handy. Especially as I had to incorporate this in a build process
– Buzut
2 days ago
Just add the script to other build scripts, I find it more readable than doubly nested bash -c.
– choroba
2 days ago
Well, it's a matter of taste. Now every option is specified so if someone encounters the same issue, he'll choose for himself :)
– Buzut
2 days ago
@mosvy: Thanks, fixed.
– choroba
yesterday
add a comment |
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
11
down vote
accepted
You could use bash -c
within the find -exec
command and use the positional parameter with the bash command:
find . ( -name '*.jpg' -o -name '*.jpeg' ) -exec bash -c 'cjpeg -quality 80 "$1" > "$(dirname "$1")/optimized_$(basename "$1")"' sh {} ;
That way {}
is provided with $1
.
The sh
before the {}
tells the inner shell its "name", the string used here is used in e.g. error messages. This is discussed more in this answer on stackoverflow.
add a comment |
up vote
11
down vote
accepted
You could use bash -c
within the find -exec
command and use the positional parameter with the bash command:
find . ( -name '*.jpg' -o -name '*.jpeg' ) -exec bash -c 'cjpeg -quality 80 "$1" > "$(dirname "$1")/optimized_$(basename "$1")"' sh {} ;
That way {}
is provided with $1
.
The sh
before the {}
tells the inner shell its "name", the string used here is used in e.g. error messages. This is discussed more in this answer on stackoverflow.
add a comment |
up vote
11
down vote
accepted
up vote
11
down vote
accepted
You could use bash -c
within the find -exec
command and use the positional parameter with the bash command:
find . ( -name '*.jpg' -o -name '*.jpeg' ) -exec bash -c 'cjpeg -quality 80 "$1" > "$(dirname "$1")/optimized_$(basename "$1")"' sh {} ;
That way {}
is provided with $1
.
The sh
before the {}
tells the inner shell its "name", the string used here is used in e.g. error messages. This is discussed more in this answer on stackoverflow.
You could use bash -c
within the find -exec
command and use the positional parameter with the bash command:
find . ( -name '*.jpg' -o -name '*.jpeg' ) -exec bash -c 'cjpeg -quality 80 "$1" > "$(dirname "$1")/optimized_$(basename "$1")"' sh {} ;
That way {}
is provided with $1
.
The sh
before the {}
tells the inner shell its "name", the string used here is used in e.g. error messages. This is discussed more in this answer on stackoverflow.
edited 2 days ago
answered 2 days ago
oliv
1,626311
1,626311
add a comment |
add a comment |
up vote
8
down vote
You have an answer(https://unix.stackexchange.com/a/481687/4778), but here is why.
The redirection >
, and also pipes |
, and $
expansion, are all done by the shell before the command is executed. Therefore stdout is redirected to optimized_{}
, before find
is started.
add a comment |
up vote
8
down vote
You have an answer(https://unix.stackexchange.com/a/481687/4778), but here is why.
The redirection >
, and also pipes |
, and $
expansion, are all done by the shell before the command is executed. Therefore stdout is redirected to optimized_{}
, before find
is started.
add a comment |
up vote
8
down vote
up vote
8
down vote
You have an answer(https://unix.stackexchange.com/a/481687/4778), but here is why.
The redirection >
, and also pipes |
, and $
expansion, are all done by the shell before the command is executed. Therefore stdout is redirected to optimized_{}
, before find
is started.
You have an answer(https://unix.stackexchange.com/a/481687/4778), but here is why.
The redirection >
, and also pipes |
, and $
expansion, are all done by the shell before the command is executed. Therefore stdout is redirected to optimized_{}
, before find
is started.
answered 2 days ago
ctrl-alt-delor
9,87031954
9,87031954
add a comment |
add a comment |
up vote
3
down vote
The redirection needs to be quoted to avoid that the present shell interprets it.
But quoting it will also avoid the output of the command to be redirected.
The known solution to this is to call a shell:
find . -name '*.jpg' -exec sh -c 'echo "$1" >"$1".new' called_shell '{}' ;
In this case, the redirection (>
) is quoted on the present shell and works correctly inside the called shell. The called_shell
is used as the $0
parameter (the name) of the child shell (sh
).
That works well if a suffix is added the name of the file, but not if you use a prefix. For a prefix to work you need both to remove the ./
that find prepend to filenames with ${1#./}
and to use the -execdir
option.
You may (or may not) want to use the -iname
option so that files named *.JPG
or *.JpG
or other variations are also included.
find . ( -iname '*.jpg' -o -iname '*.jpeg' ) -execdir sh -c '
cjpeg -quality 80 "$1" > optimized_"${1#./}"
' called_shell '{}' ;
And, you may (or may not) also want to call the shell once per directory instead of once per file by adding a loop (for f do … ; done
) and a +
at the end:
find . ( -iname '*.jpg' -o -iname '*.jpeg' ) -execdir sh -c '
for f; do cjpeg -quality 80 "$f" > optimized_"${f#./}"; done
' called_shell '{}' +
And, finally, as cjpeg
is able to directly write to a file, the redirection could be avoided as:
find . ( -iname '*.jpg' -o -iname '*.jpeg' ) -execdir sh -c '
for f; do cjpeg -quality 80 "$f" -outfile optimized_"${f#./}"; done
' called_shell '{}' +
add a comment |
up vote
3
down vote
The redirection needs to be quoted to avoid that the present shell interprets it.
But quoting it will also avoid the output of the command to be redirected.
The known solution to this is to call a shell:
find . -name '*.jpg' -exec sh -c 'echo "$1" >"$1".new' called_shell '{}' ;
In this case, the redirection (>
) is quoted on the present shell and works correctly inside the called shell. The called_shell
is used as the $0
parameter (the name) of the child shell (sh
).
That works well if a suffix is added the name of the file, but not if you use a prefix. For a prefix to work you need both to remove the ./
that find prepend to filenames with ${1#./}
and to use the -execdir
option.
You may (or may not) want to use the -iname
option so that files named *.JPG
or *.JpG
or other variations are also included.
find . ( -iname '*.jpg' -o -iname '*.jpeg' ) -execdir sh -c '
cjpeg -quality 80 "$1" > optimized_"${1#./}"
' called_shell '{}' ;
And, you may (or may not) also want to call the shell once per directory instead of once per file by adding a loop (for f do … ; done
) and a +
at the end:
find . ( -iname '*.jpg' -o -iname '*.jpeg' ) -execdir sh -c '
for f; do cjpeg -quality 80 "$f" > optimized_"${f#./}"; done
' called_shell '{}' +
And, finally, as cjpeg
is able to directly write to a file, the redirection could be avoided as:
find . ( -iname '*.jpg' -o -iname '*.jpeg' ) -execdir sh -c '
for f; do cjpeg -quality 80 "$f" -outfile optimized_"${f#./}"; done
' called_shell '{}' +
add a comment |
up vote
3
down vote
up vote
3
down vote
The redirection needs to be quoted to avoid that the present shell interprets it.
But quoting it will also avoid the output of the command to be redirected.
The known solution to this is to call a shell:
find . -name '*.jpg' -exec sh -c 'echo "$1" >"$1".new' called_shell '{}' ;
In this case, the redirection (>
) is quoted on the present shell and works correctly inside the called shell. The called_shell
is used as the $0
parameter (the name) of the child shell (sh
).
That works well if a suffix is added the name of the file, but not if you use a prefix. For a prefix to work you need both to remove the ./
that find prepend to filenames with ${1#./}
and to use the -execdir
option.
You may (or may not) want to use the -iname
option so that files named *.JPG
or *.JpG
or other variations are also included.
find . ( -iname '*.jpg' -o -iname '*.jpeg' ) -execdir sh -c '
cjpeg -quality 80 "$1" > optimized_"${1#./}"
' called_shell '{}' ;
And, you may (or may not) also want to call the shell once per directory instead of once per file by adding a loop (for f do … ; done
) and a +
at the end:
find . ( -iname '*.jpg' -o -iname '*.jpeg' ) -execdir sh -c '
for f; do cjpeg -quality 80 "$f" > optimized_"${f#./}"; done
' called_shell '{}' +
And, finally, as cjpeg
is able to directly write to a file, the redirection could be avoided as:
find . ( -iname '*.jpg' -o -iname '*.jpeg' ) -execdir sh -c '
for f; do cjpeg -quality 80 "$f" -outfile optimized_"${f#./}"; done
' called_shell '{}' +
The redirection needs to be quoted to avoid that the present shell interprets it.
But quoting it will also avoid the output of the command to be redirected.
The known solution to this is to call a shell:
find . -name '*.jpg' -exec sh -c 'echo "$1" >"$1".new' called_shell '{}' ;
In this case, the redirection (>
) is quoted on the present shell and works correctly inside the called shell. The called_shell
is used as the $0
parameter (the name) of the child shell (sh
).
That works well if a suffix is added the name of the file, but not if you use a prefix. For a prefix to work you need both to remove the ./
that find prepend to filenames with ${1#./}
and to use the -execdir
option.
You may (or may not) want to use the -iname
option so that files named *.JPG
or *.JpG
or other variations are also included.
find . ( -iname '*.jpg' -o -iname '*.jpeg' ) -execdir sh -c '
cjpeg -quality 80 "$1" > optimized_"${1#./}"
' called_shell '{}' ;
And, you may (or may not) also want to call the shell once per directory instead of once per file by adding a loop (for f do … ; done
) and a +
at the end:
find . ( -iname '*.jpg' -o -iname '*.jpeg' ) -execdir sh -c '
for f; do cjpeg -quality 80 "$f" > optimized_"${f#./}"; done
' called_shell '{}' +
And, finally, as cjpeg
is able to directly write to a file, the redirection could be avoided as:
find . ( -iname '*.jpg' -o -iname '*.jpeg' ) -execdir sh -c '
for f; do cjpeg -quality 80 "$f" -outfile optimized_"${f#./}"; done
' called_shell '{}' +
edited 2 days ago
answered 2 days ago
Isaac
9,42911443
9,42911443
add a comment |
add a comment |
up vote
3
down vote
cjpeg
has an option that lets you write to a named file, rather than standard output. If your version of find
supports the -execdir
option, you can take advantage of that to make the redirection unnecessary.
find . ( -name '*.jpg' -o -name '*.jpeg' )
-execdir cjpeg -quality 80 -outfile optimized_'{}' '{}' ;
Note: this actually assumes the BSD version of find
, which appears to strip the leading ./
from the file name when exanding to {}
. (Or conversely, GNU find
adds ./
to the name. There's no standard to say which behavior is "right".)
If yourfind
supports-execdir
, you can use that instead of-exec
. It causes the command to run in the directory where the file was found, and{}
will becomeaa.jpg
instead of./t2/aa.jpg
.
– chepner
2 days ago
Still in error:cjpeg: can't open optimized_./aa.jpg
.
– Isaac
2 days ago
Hm, that appears to be a difference between GNUfind
and BSDfind
. (The perils of using non-standard extensions.)
– chepner
2 days ago
A filename without a leading./
seems to be more prone to errors. A reasonable solution is proposed in this answer.
– Isaac
2 days ago
add a comment |
up vote
3
down vote
cjpeg
has an option that lets you write to a named file, rather than standard output. If your version of find
supports the -execdir
option, you can take advantage of that to make the redirection unnecessary.
find . ( -name '*.jpg' -o -name '*.jpeg' )
-execdir cjpeg -quality 80 -outfile optimized_'{}' '{}' ;
Note: this actually assumes the BSD version of find
, which appears to strip the leading ./
from the file name when exanding to {}
. (Or conversely, GNU find
adds ./
to the name. There's no standard to say which behavior is "right".)
If yourfind
supports-execdir
, you can use that instead of-exec
. It causes the command to run in the directory where the file was found, and{}
will becomeaa.jpg
instead of./t2/aa.jpg
.
– chepner
2 days ago
Still in error:cjpeg: can't open optimized_./aa.jpg
.
– Isaac
2 days ago
Hm, that appears to be a difference between GNUfind
and BSDfind
. (The perils of using non-standard extensions.)
– chepner
2 days ago
A filename without a leading./
seems to be more prone to errors. A reasonable solution is proposed in this answer.
– Isaac
2 days ago
add a comment |
up vote
3
down vote
up vote
3
down vote
cjpeg
has an option that lets you write to a named file, rather than standard output. If your version of find
supports the -execdir
option, you can take advantage of that to make the redirection unnecessary.
find . ( -name '*.jpg' -o -name '*.jpeg' )
-execdir cjpeg -quality 80 -outfile optimized_'{}' '{}' ;
Note: this actually assumes the BSD version of find
, which appears to strip the leading ./
from the file name when exanding to {}
. (Or conversely, GNU find
adds ./
to the name. There's no standard to say which behavior is "right".)
cjpeg
has an option that lets you write to a named file, rather than standard output. If your version of find
supports the -execdir
option, you can take advantage of that to make the redirection unnecessary.
find . ( -name '*.jpg' -o -name '*.jpeg' )
-execdir cjpeg -quality 80 -outfile optimized_'{}' '{}' ;
Note: this actually assumes the BSD version of find
, which appears to strip the leading ./
from the file name when exanding to {}
. (Or conversely, GNU find
adds ./
to the name. There's no standard to say which behavior is "right".)
edited 2 days ago
answered 2 days ago
chepner
5,2901323
5,2901323
If yourfind
supports-execdir
, you can use that instead of-exec
. It causes the command to run in the directory where the file was found, and{}
will becomeaa.jpg
instead of./t2/aa.jpg
.
– chepner
2 days ago
Still in error:cjpeg: can't open optimized_./aa.jpg
.
– Isaac
2 days ago
Hm, that appears to be a difference between GNUfind
and BSDfind
. (The perils of using non-standard extensions.)
– chepner
2 days ago
A filename without a leading./
seems to be more prone to errors. A reasonable solution is proposed in this answer.
– Isaac
2 days ago
add a comment |
If yourfind
supports-execdir
, you can use that instead of-exec
. It causes the command to run in the directory where the file was found, and{}
will becomeaa.jpg
instead of./t2/aa.jpg
.
– chepner
2 days ago
Still in error:cjpeg: can't open optimized_./aa.jpg
.
– Isaac
2 days ago
Hm, that appears to be a difference between GNUfind
and BSDfind
. (The perils of using non-standard extensions.)
– chepner
2 days ago
A filename without a leading./
seems to be more prone to errors. A reasonable solution is proposed in this answer.
– Isaac
2 days ago
If your
find
supports -execdir
, you can use that instead of -exec
. It causes the command to run in the directory where the file was found, and {}
will become aa.jpg
instead of ./t2/aa.jpg
.– chepner
2 days ago
If your
find
supports -execdir
, you can use that instead of -exec
. It causes the command to run in the directory where the file was found, and {}
will become aa.jpg
instead of ./t2/aa.jpg
.– chepner
2 days ago
Still in error:
cjpeg: can't open optimized_./aa.jpg
.– Isaac
2 days ago
Still in error:
cjpeg: can't open optimized_./aa.jpg
.– Isaac
2 days ago
Hm, that appears to be a difference between GNU
find
and BSD find
. (The perils of using non-standard extensions.)– chepner
2 days ago
Hm, that appears to be a difference between GNU
find
and BSD find
. (The perils of using non-standard extensions.)– chepner
2 days ago
A filename without a leading
./
seems to be more prone to errors. A reasonable solution is proposed in this answer.– Isaac
2 days ago
A filename without a leading
./
seems to be more prone to errors. A reasonable solution is proposed in this answer.– Isaac
2 days ago
add a comment |
up vote
1
down vote
Create a script cjq80:
#!/bin/bash
cjpeg -quality 80 "$1" > "${1%/*}"/optimized_"${1##*/}"
Make it executable
chmod u+x cjq80
And use it in -exec:
find . ( -name '*.jpg' -o -name '*.jpeg' ) -exec cjq80 '{}' ;
I had though about this, but it's not very handy. Especially as I had to incorporate this in a build process
– Buzut
2 days ago
Just add the script to other build scripts, I find it more readable than doubly nested bash -c.
– choroba
2 days ago
Well, it's a matter of taste. Now every option is specified so if someone encounters the same issue, he'll choose for himself :)
– Buzut
2 days ago
@mosvy: Thanks, fixed.
– choroba
yesterday
add a comment |
up vote
1
down vote
Create a script cjq80:
#!/bin/bash
cjpeg -quality 80 "$1" > "${1%/*}"/optimized_"${1##*/}"
Make it executable
chmod u+x cjq80
And use it in -exec:
find . ( -name '*.jpg' -o -name '*.jpeg' ) -exec cjq80 '{}' ;
I had though about this, but it's not very handy. Especially as I had to incorporate this in a build process
– Buzut
2 days ago
Just add the script to other build scripts, I find it more readable than doubly nested bash -c.
– choroba
2 days ago
Well, it's a matter of taste. Now every option is specified so if someone encounters the same issue, he'll choose for himself :)
– Buzut
2 days ago
@mosvy: Thanks, fixed.
– choroba
yesterday
add a comment |
up vote
1
down vote
up vote
1
down vote
Create a script cjq80:
#!/bin/bash
cjpeg -quality 80 "$1" > "${1%/*}"/optimized_"${1##*/}"
Make it executable
chmod u+x cjq80
And use it in -exec:
find . ( -name '*.jpg' -o -name '*.jpeg' ) -exec cjq80 '{}' ;
Create a script cjq80:
#!/bin/bash
cjpeg -quality 80 "$1" > "${1%/*}"/optimized_"${1##*/}"
Make it executable
chmod u+x cjq80
And use it in -exec:
find . ( -name '*.jpg' -o -name '*.jpeg' ) -exec cjq80 '{}' ;
edited yesterday
answered 2 days ago
choroba
25.5k44269
25.5k44269
I had though about this, but it's not very handy. Especially as I had to incorporate this in a build process
– Buzut
2 days ago
Just add the script to other build scripts, I find it more readable than doubly nested bash -c.
– choroba
2 days ago
Well, it's a matter of taste. Now every option is specified so if someone encounters the same issue, he'll choose for himself :)
– Buzut
2 days ago
@mosvy: Thanks, fixed.
– choroba
yesterday
add a comment |
I had though about this, but it's not very handy. Especially as I had to incorporate this in a build process
– Buzut
2 days ago
Just add the script to other build scripts, I find it more readable than doubly nested bash -c.
– choroba
2 days ago
Well, it's a matter of taste. Now every option is specified so if someone encounters the same issue, he'll choose for himself :)
– Buzut
2 days ago
@mosvy: Thanks, fixed.
– choroba
yesterday
I had though about this, but it's not very handy. Especially as I had to incorporate this in a build process
– Buzut
2 days ago
I had though about this, but it's not very handy. Especially as I had to incorporate this in a build process
– Buzut
2 days ago
Just add the script to other build scripts, I find it more readable than doubly nested bash -c.
– choroba
2 days ago
Just add the script to other build scripts, I find it more readable than doubly nested bash -c.
– choroba
2 days ago
Well, it's a matter of taste. Now every option is specified so if someone encounters the same issue, he'll choose for himself :)
– Buzut
2 days ago
Well, it's a matter of taste. Now every option is specified so if someone encounters the same issue, he'll choose for himself :)
– Buzut
2 days ago
@mosvy: Thanks, fixed.
– choroba
yesterday
@mosvy: Thanks, fixed.
– choroba
yesterday
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f481685%2ffind-exec-not-available-after%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Isn't there a
>
missing in the third code sample?– choroba
2 days ago
1
Even your first line is nonstandard and thus non-portable. Try to avoid command lines where
{}
appears in a longer strings as such strings are typically not expanded.– schily
2 days ago
That first example does not do what you say.
– ctrl-alt-delor
2 days ago
1
You have fixed your question: I would no-longer change it.
– ctrl-alt-delor
2 days ago
1
For what it's worth, the primary reason that your redirection does not work as you wanted is that it is handled by the shell from which you launch
find
, once, and applied to thefind
command itself. The{}
has no special meaning in that context. The redirection is not an argument tofind
, and it certainly is not part of the-exec
clause.– John Bollinger
2 days ago