1

I have the below directory structure. I need to find the directories in which a file called log.xml exists and remove all of them completely, except the directory which is pointed to by a specific symbolic link.

For example, /dir1/main/app1/v004/ and /dir1/main/app2/v004/log.xml are pointed to by a symbolic link, so they should not be deleted.

Also how possible to remove the directory except pointed to by a symbolic link, without finding log.xml.

Could you please help with the correct solution for that?

/dir1/main/app1/v001/
/dir1/main/app1/v002/log.xml
/dir1/main/app1/v003/log.xml
/dir1/main/app1/v004/log.xml
/dir1/main/app1/v005/log.xml
/dir1/ln1/app -> /dir1/main/app2/v004

/dir1/main/app2/v001/
/dir1/main/app2/v002/log.xml
/dir1/main/app2/v003/log.xml
/dir1/main/app2/v004/log.xml
/dir1/main/app2/v005/log.xml
/dir1/ln2/app -> /dir1/main/app2/v004
1
  • So the result should be that /dir1/main/app/v001 and /dir1/main/app/v004 remain?
    – Kusalananda
    Commented Feb 9, 2022 at 9:08

2 Answers 2

0

Assuming you want to delete all the subdirectories of the app directory apart from v001 (which does not contain log.xml) and v004 (which is being pointed to by the symbolic link):

for topdir in /dir1 /dir2; do

    for dirpath in "$topdir"/main/app/*/; do
            if [ -e "$dirpath/log.xml" ] && ! [ "$dirpath" -ef "$topdir"/ln/app ]
            then
                    printf 'Would remove "%s"\n' "$dirpath"
                    # rm -rf "$dirpath"
            fi
    done

done

The outer loop is used to loop over the two top-most directories /dir1 and /dir2 (you may possibly want to use /dir[12] as a globbing pattern there). The name of the top-directory is kept in the topdir variable.

The inner loop iterates over the subdirectories beneath app, beneath $topdir. If the subdirectory contains something called log.xml (the first test, with -e) and if the directory is not pointed to by the "$topdir"/ln/app symbolic link (the second test, with -ef), then it may be removed.

The -e test is a standard test for the existence of the given pathname. The -ef test is non-standard but implemented by the bash shell, and it tests whether two pathnames refer to the same file (or directory in this case) after resolving symbolic links.

The actual removal is commented out for safety. You should test this on data you have previously backed up before enabling the rm command.

To remove the subdirectories regardless of whether they contain something called log.xml, remove the -e test, so that the if statement looks like

if ! [ "$dirpath" -ef "$topdir"/ln/app ]; then
        printf 'Would remove "%s"\n' "$dirpath"
        # rm -rf "$dirpath"
fi
11
  • @Emin If you have clarifications to your question, then please edit your question. It is difficult to read code and long list of pathnames in comments, and comments may be deleted at any time.
    – Kusalananda
    Commented Feb 9, 2022 at 9:50
  • I have edited question. could you please review and help with correct way?
    – Emin
    Commented Feb 9, 2022 at 9:53
  • @Emin See updated answer.
    – Kusalananda
    Commented Feb 9, 2022 at 9:55
  • thank you very much. Could you please also help in case with removing all dir except pointed to symlink without checking log.xml.
    – Emin
    Commented Feb 9, 2022 at 10:05
  • @Emin Just remove the -e test so that you have if ! [ "$dirpath" -ef "$topdir"/ln/app ]; then ....
    – Kusalananda
    Commented Feb 9, 2022 at 10:14
0

GNU find has an option -samefile, you need to include -L option for this to work.

Take a look at the output of the following two commands

(cd /dir1 ; find -L . -samefile ln/app ) # your file and link

(cd /dir1 ; find -L . -not -samefile ln/app ) # everything other than your file and link

The second should produce a list of the files you wish to remove. Maybe you only want to list the files and not directories, if so then just add -type f

find -L . -type f -samefile ln/app)

removing the files is trivial, just append to the find command an exec action, eg -exec rm -v {} \;

3
  • This would probably remove all log.xml files (and whatever other files are stored in those directories), as they are not pointed to by the symbolic link.
    – Kusalananda
    Commented Feb 9, 2022 at 9:43
  • Well yes, the question doesn't really specify what else is in those directories, I've provided a method to identify the linked files, and the inverse as a file list, which I thought was the essence of his question.
    – X Tian
    Commented Feb 9, 2022 at 9:48
  • Thank you very much for suggestion.
    – Emin
    Commented Feb 9, 2022 at 10:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .