I wrote a script that searches for a file then outputs it. This script has worked up until the point where I tried using the du command. the code is:


echo "Enter either file name or format:"
    read File

echo "Input the absolute path to directory:"
    read Dir

echo "Enter \"/path/to/directory/filename\" to store outputs on the filename:"
    read results

#cd $Dir; 
#for dir in */; do 
#   echo $Dir; 
#done | xargs -P0 -I_ echo "sudo find _ -type f -name \*$File\* " > temp.txt

cd $Dir; 
for dir in */; do 
  echo $dir; 
done | xargs -P0 -I_ sudo find _ -type f -name \*$File\* | du >> $results

Basically it searches the directory you wish to search for the file you inputted, and xargs is there to utilize as many cores as possible.

I only need now to output the size of the file along with the files that will be outputted to the results file. doing this myself gives me the wrong output which consists of every directory, and does not find the files I search for instead. Any ideas?

  • @bu5hman original it was a one-liner
    – alecxs
    Jun 13, 2020 at 12:25
  • 1
    Effectively it still is (all ; are still there) though since it is in a script it makes little odds except in readability. Am sure OP will let me know if the readability edit contradicts the intent and I will roll back.
    – bu5hman
    Jun 13, 2020 at 21:25
  • @bu5hman Thanks for making it more readable its absolutely fine, no need to change back. Jun 15, 2020 at 15:26

1 Answer 1


Your code has some bugs

cd $Dir

should not used in script because cd may fail but your script is continuing (and will fail for spaces in folder name). better do a check if cd was successful, two examples:

cd "$Dir" || exit 2
cd "$Dir" && for dir in */; do

sudo should not used in script. better run the script with right permissions (just opinion)

sudo find _ -type f -name \*$File\*

find can be placed inside the loop if loop is requirement, no need for xargs (opinion)

for dir in */; do echo $dir; done

the for loop makes less sense (because it's nothing inside) and could just replaced with ls -d */. it will just print subfolders (excluded hidden starting with .) even find */ directly will work (better cd "$Dir" && find ./*/)

\*$File\* | du >> $results

don't pipe a string to du it will not do what you expect. give file names as arguments, you can do this with xargs or better use find -exec (terminated with \; for processing each file on its own, or with + for passing all file names as argument at once)

for dir in */; find "$dir" -type f -iname "*$File*" -exec du {} + >> "$results"; done

However, instead of running find on subfolders "$dir" you could just run it straight on parent "$Dir" with -mindepth 2 and for file size i recommend using stat with desired output, for example stat -c %s$'\t'%n (except you really want to have disk usage instead)

find "$Dir" -mindepth 2 -type f -iname "*$File*" -exec stat -c %s$'\t'%n {} + >> "$results"

or with xargs -0 if too many arguments passed to stat

find "$Dir" -mindepth 2 -type f -iname "*$File*" -print0 | xargs -0 -P0 stat -c %s$'\t'%n >> "$results"

for a more safe way to process folder names i recommend find while read loop with NUL terminated results (GNU extension -print0) see this answers for reference (although with xargs -I_ find _ you have found a working solution)

How to loop through file names returned by find?


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .