You need to sort by the last field (considering /
as a field separator). Unfortunately, I can't think of a tool that can do this when the number of fields varies (if only sort -k
could take negative values).
To get around this, you'll have to do a decorate-sort-undecorate. That is, take the filename and put it at the beginning followed by a field separator, then do a sort, then remove the first column and field separator.
find . ! -path "./build*" -name "*.txt" |\
awk -vFS=/ -vOFS=/ '{ print $NF,$0 }' |\
sort -n -t / |\
cut -f2- -d/
That awk
command says the field separator FS
is set to /
; this affects the way it reads fields. The output field separator OFS
is also set to /
; this affects the way it prints records. The next statement says print the last column (NF
is the number of fields in the record, so it also happens to be the index of the last field) as well as the whole record ($0
is the whole record); it will print them with the OFS between them. Then the list is sort
ed, treating /
as the field separator - since we have the filename first in the record, it will sort by that. Then the cut
prints only fields 2 through the end, again treating /
as the field separator.
while [ -f /tmp/restarting_server ] ; do {
[ $((i=i+1)) -ge 10 ] && exit 1
sleep 1
} ; done
You dont need find
if you know already the exact filename, pathname, and conditions under which a file should be acceptably found.
So the other problem - exiting your script from your -exec
statement - is maybe not the problem you consider it to be. find
doesn't build in an option for kill
ing its parent shell because the shell already provides it.
find … -exec sh -c kill\ $$ \;
Consider also that you can use this construct for signalling based on existing paths even if you're not certain before hand where they'll be:
trap 'stuff to do' USR1
… #later…
find … -exec sh -c kill\ -USR1\ $$ \;
And this opens a lot of other options to you as well:
find … -exec sh -c exec…
EDIT:
I've just thought of other options involving parameter expansion
to make your shell exit without find
's -exec
at all that could be used in other ways:
hold_file="$(find . -name file)"
${hold_file:+false} : || exit 1
or
N= ; hold_file="$(find . -name file)"
${hold_file:+${N:?lock file remains, exiting...}}
Both of these will only cause an exit if the variable to which you assign find
's stdout
is neither null
or unset. And of course, should you desire to fail based on an empty find, you can do the same with :-
instead of :+
and omitting the $N
ull value variable entirely.
Or just to alter find
's exit status:
$(find . -name file -exec echo false \; ) : || exit 1
Best Answer
You can use an "in-line" shell script, and parameter expansion:
or (more efficiently, if your
find
supports it)