开发者

Removing old directories with logs

My IM stores the logs according to the contact name. I have created a file with the list of active contacts. My problem is following:

I would like to create a bash script with read the active contacts names from the file and compare it with the directories. If the directory name wouldn't be found on the list, it would be moved to another directory (let's call it "archive"). I try to visualise it for you.

contact1

contact2

  • content of the dir

contact1

contact2

contact3

contact4

  • after running of the script, the content fo the dir:

contact1

contact2

contact3 ==> ../archive

contact4 ==> ../archive


You could use something like this:

mv $(ls | grep -v -x -F -f ../file.txt) ../archive

Where ../file.txt contains the names of the directories that should not be moved. It is assumed here that the current directory only contains directories, if that is not the case, ls should be replaced with something else. Note that the command fails if there are no directories that should be moved.

Since in the comments to the other answer you state that directories with whitespace in the name can occur, you could replace this by:

for i in *
do
    echo $i | grep -v -x -q -F -f ../file.txt && mv "$i" ../archive
done


This is an improved version of marcog's answer. Note that the associative array requires Bash 4.

#!/bin/bash
sourcedir=/path/to/foo
destdir=/path/to/archive
contactfile=/path/to/list

declare -A contacts

while read -r contact
do
    contacts[$contact]=1
done < "$contactfile"

for contact in "$sourcedir"/*
do
    if [[ -f $contact ]]
    then
        index=${contact##*/}
        if [[ ! ${contacts[$index]} ]]
        then
            mv "$contact" "$destdir"
        fi
    fi
done

Edit:

If you're moving directories instead of files, then change the for loop above to look like this:

for contact in "$sourcedir"/*/
do
    index=${contact/%\/}
    index=${index##*/}
    if [[ ! ${contacts[$index]} ]]
    then
        mv "$contact" "$destdir"
    fi
done


There might be a more concise solution, but this works. I'd strongly recommend prefixing the mv with echo to test it out first, otherwise you could end up with a serious mess if it doesn't do what you want.

declare -A contacts
for contact in "$@"
do
  contacts[$contact]=1
done
ls a | while read contact
do
  if [[ ! ${contacts[$contact]} ]]
  then
    mv "a/$contact" ../archive
  fi
done
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜