2

I am teaching myself more (l)unix skills and wanted to see if I could begin to write a program that will eventually read all .gz files and expand them. However, I want it to be super dynamic.

    #!/bin/bash

dir=~/derp/herp/path/goes/here

for file in $(find dir -name '*gz')
    do 
       echo $file
    done

So when I excute this file, I simply go

bash derp.sh.

I don't like this. I feel the script is too brittle. How can I rework my for loop so that I can say

bash derp.sh ~/derp/herp/path/goes/here (1) 

I tried re-coding it as follows:

for file in $*

However, I don't want to have to type in bash

derp.sh ~/derp/herp/path/goes/here/*.gz. 

How could I rewrite this so I could simply type what is in (1)? I feel I must be missing something simple?

Note

I tried

for file in $*/*.gz and that obviously did not work. I appreciate your assistance, my sources have been a wrox unix text, carpentry v5, and man files. Unfortunately, I haven't found anything that will what I want.

Thanks, GeekyOmega

GeekyOmega
  • 1,235
  • 6
  • 16
  • 34

2 Answers2

2
for dir in "$@"
do
    for file in "$dir"/*.gz
    do 
       echo $file
    done
done

Notes:

  • In the outer loop, dir is assigned successively to each argument given on the command line. The special form "$@" is used so that the directory names that contain spaces will be processed correctly.

  • The inner loop runs over each .gz file in the given directory. By placing $dir in double-quotes, the loop will work correctly even if the directory name contains spaces. This form will also work correctly if the gz file names have spaces.

John1024
  • 109,961
  • 14
  • 137
  • 171
1
#!/bin/bash
for file in $(find "$@" -name '*.gz')
do 
   echo $file
done

You'll probably prefer "$@" instead of $*; if you were to have spaces in filenames, like with a directory named My Documents and a directory named Music, $* would effectively expand into:

find My Documents Music -name '*.gz'

where "$@" would expand into:

find "My Documents" "Music" -name '*.gz'

Requisite note: Using for file in $(find ...) is generally regarded as a bad practice, because it does tend to break if you have spaces or newlines in your directory structure. Using nested for loops (as in John's answer) is often a better idea, or using find -print0 and read as in this answer.

Community
  • 1
  • 1
Jeff Bowman
  • 90,959
  • 16
  • 217
  • 251
  • 1
    @John1024: You beat me to the punch! That addition is already in my editing window. :) – Jeff Bowman Jul 15 '14 at 05:13
  • Thank you both John and Jeff. I learned a lot from this question! You both rock. I feel inspired to keep studying and also to measure the merits of both approaches. Thank you. – GeekyOmega Jul 15 '14 at 05:16