I wanted to show on stdout that a file was found right after it happens due to indicate the activity of long search. Further more I want to store the result of the find in a file.
find . -name Makefile -type f -print -exec echo -n "." | tee -a testPaths.log
prints dot and path to both file and stdout due to piping (dot is printed right after a file is found)
while
find . -name Makefile -type f 2> /dev/null | while read FILE; do printf "."; echo $FILE > testPaths.log; done
prints the right characters to right places, but the printing of dot is execute just after the find finishes its work on the whole directory set.
Any other idea?
(at this point the piping mechanism is not clear for me: why tee is executed after each file found and why not executed while (just at the end)? Maybe this is the behaviour of while (like xargs echo)?)
I don't know if it works but I think it should work ^^'
find . -name Makefile -type f -print -exec tee -a testPaths.log | echo -n "."
What it is supposed to do:
first writes the found file to testPaths.log and then echo a dot, not the other way around
Sorry for explaining so bad ^^'
btw @scottn: if you take a look at find's man page:
maybe thats why it doesn't print the dot directly to stdout? Sorry I could also be terribly wrong about it ^^'
It just writes a dot to stdout and done. Maybe tee has no input.
@scottn:
I have tested it on a large folder set. I think that data is collected till end of find, then it is pushed to pipe on by one. In case of "| while" I see that the full time of search elapses and then everything is printed out in a sec.
I would really like to help more but for some reason my ubuntu-terminal rejects the command because "-exec needs arguments" :s
For the meantime:
I don't know if this will work but it's worth trying:
Another approach where we can do whatever we like each time we find a file.
Also improved order of parameters on the "find" line which should speed it up.
>testPaths.log
echo -n "Searching "
#
find . -type f -name Makefile -print|while read filename
do
# Output filename to file
echo "${filename}" >> testPaths.log
# Output dot to screen with no linefeed
echo -n "."
done
# Output a linefeed
echo ""
echo "Finished"
Sorry "vercsab" but the script just posted does not work because ${path} does not receive the filename from the find. The superfluous "-exec" parameters wreck the function of the script.
When dealing with unknown filenames in a script, always put them in double quotes.
(No comment about using complex relative paths because I guess that this was a quick test not a production script).
Hint: Using ${path} to contain a filename not a path obfuscates your code.
# Create an empty file
> testPaths.log
echo -n "Searching"
find ./../../../40_Implementation_test -type f -name Makefile -print | while read path
do
echo -n "."
echo "${path}" >> testPaths.log
done
echo ""
Footnote: I really think you need to read-up about pipelines. The "pipe" character "|" is not a sequential command separator in unix shell scripting (but the semi-colon character ";" is). The pipe characer "|" signifies that the output to STDOUT from the first command is to be fed directly into the input STDIN in the second command.