Indeciski
Indeciski

Reputation: 53

In ksh how do I iterate through a list of directories and cd to them using a loop?

Basically I have a flat file that is setup like so:

/this/is/a/log/directory | 30

/this/also/is/having/logs | 45

/this/logs/also | 60

What I'm trying to do is extract the first column of this flat file which is the directory path and check if it has more than 500 log files in it. If it does, remove all but the newest 500 files.

I was trying to do something like this

#!/bin/ksh

for each in "$(awk '{ print $1 }' flat_file)"; do

    cd "$each";

    if [ "ls -l | wc -l >= 500" ]; then
        rm `ls -t | awk 'NR>500'`

    else
        :

    fi

done

However from what I've read I cannot cd from within my script with the for loop like I was trying to do and that you can do it from within a function, at which point I basically just made a function and copied that code into it, and it of course didn't work (not too familiar with shell scripting). Something similar to Python's OS module where I could just use os.listdir() and pass in the directory names would be perfect, however I have yet to be able to figure out an easy way to do this.

Upvotes: 2

Views: 1089

Answers (1)

shellter
shellter

Reputation: 37288

OK, you're on the right track, but you'll confuse the csh programmers that look at your code with for each. Why not

 for dir in $( awk '{ print $1 }' flat_file ) ; do
      cd "$dir"
      if (( $(ls -l | wc -l) >= 500 )); then
            rm $( ls -t | awk 'NR>500' )
         fi
      cd -
 done

Lots of little things in your original code. Why use backticks sometimes, when you are using the preferred form of cmd-sub $( cmd ) other times.

Enclosing your "$(awk '{print $1}' file)" in dbl-quotes will turn the complete output of the cmd-substition into 1 long string, it won't find a dir named "dir1 dir2 dir3 .... dirn", right?

You don't need a null (:) else. You can just eliminate that block of code.

ksh supports math operations inside (( .... )) pairs (just like bash).

cd - will take you back to the previous directory.

Learn to use the shell debug/trace, set -vx. it will show you first, what it going to be executed (sometimes a very large loop structure) and then it will show each line that does get executed, preceded with + and where variables have been converted into their values. You might also want to use export PS4='$LINENO >' so debugging will show current lineNo that is being executed.

IHTH

Upvotes: 2

Related Questions