How would you do this in bash
+6
A:
ls -atrd */ | head --lines=-4 | xargs rm -rf
Edit: added 'a' argument to ls
Leigh Caldwell
2008-09-16 12:55:29
this will leave 4 most recently modified directories instead of the 4 most recently created, won't notice directories starting with a dot, head will break for names containing newlines, xargs will break for names containing whitespace, and rm will print an error message if there's nothing to delete.
Alexey Feldgendler
2008-09-16 13:00:31
Good points. I have now added 'a' to ls to capture directories with a dot, and grepped to get rid of the current and parent directories, but you're right. This is a simple answer with some important limitations as you have pointed out.
Leigh Caldwell
2008-09-16 13:36:13
Correction: no grep is needed to filter the current and parent directory as they are not shown by ls */
Leigh Caldwell
2008-09-16 13:37:46
+1
A:
Please clarify if you mean “delete all directories but the four newst ones” or “delete everything (files and directories) except for the four newest directories”.
Please also note that creation times are not known for directories. One can only tell when a directory was last modified, that is, had files added, removed or renamed.
Alexey Feldgendler
2008-09-16 12:56:27
+1
A:
you could do the following:
#!/bin/bash
#store the listing of current directory in var
mydir=`ls -t`
it=1
for file in $mydir
do
if [ $it -gt 5 ]
then
echo file $it will be deleted: $file
#rm -rf $file
fi
it=$((it+1))
done
(remove the # before rm to make it really happen ;) )
mana
2008-09-16 13:05:21
A:
Another, BSD-safe, way to do it, with arrays (why not?)
#!/bin/bash
ARRAY=( `ls -td */` )
ELEMENTS=${#ARRAY[@]}
COUNTER=4
while [ $COUNTER -lt $ELEMENTS ]; do
echo ${ARRAY[${COUNTER}]}
let COUNTER=COUNTER+1
done
mdxi
2008-09-16 13:24:35
A:
ls -trd */ | head --lines=-4 | xargs rm -rf works perfectly, thanks - these directories are only created and written to once, so there's no difference between ctime and mtime, but good point Alexey
eventi
2008-09-16 14:23:38