If you analyse the both will do the same functionality
xargs executes the command once and puts the arguments all together, whereas -exec executes the command multiple times, once per each file.
find . -type f | xargs grep "pattern"
f
ind . -type f -exec grep pattern {}
But in the case of exec it will create a separate process for each file returned by the find.So the xargs is said to be more efficient when you are going to do for large
file as it will save time and process memory.
This example may also make you understand better
For example if you want to search a pattern in the first line of the file returned by find command.
For exec it has to be used like this:
find . -type f -perm -700 -exec awk 'NR == 1 && /perl/ {print FILENAME}' {} \;
In exec we can use NR since for each file the awk command will be efxecuted and the NR will point the first line of the file.
For xargs used like this:
find . -type f -perm -700 | xargs awk 'FNR == 1 && /perl/ {print FILENAME}'
In xargs case the find command will be executed first and then for each argument awk will be executed so NR will point to the first line only for the first file and for the second file and so on it will continue to point to the first file.So in this FNR has to be used denoting the first line in each file.
This example was referred from
http://www.linuxquestions.org/questions/showthread.php?s=71bbab884c811443dde9e2f8131bb818&p=4431861#post4431861