Reputation: 53
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
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