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

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

1 Comment

I definitely gave you rep for this reply. Thank you.
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.

2 Comments

@John1024: You beat me to the punch! That addition is already in my editing window. :)
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.