Tuesday, September 11, 2007

How to Delete "Dot Dot Backslash" Files

How to remove files like this '..\logs\access-2007-09-01' in a UNIX environment. They looked like files residing inside a directory if you are living in Windows environment. In UNIX, any files that starts with a dot (.) is considered a hidden file. You need to 'ls -a' to list them out 'cos they won't show up in 'ls'. It is definitely a challenge to get rid of them.

Let's create some of these files to try things out.

$ for i in 01 02 03 04 05 06 07 08 09 10 11 12
do
  touch '..\logs\access-2007-09-'$i
done

$ ls

$ ls -a
.                          ..\logs\access-2007-09-06
..                         ..\logs\access-2007-09-07
..\logs\access-2007-09-01  ..\logs\access-2007-09-08
..\logs\access-2007-09-02  ..\logs\access-2007-09-09
..\logs\access-2007-09-03  ..\logs\access-2007-09-10
..\logs\access-2007-09-04  ..\logs\access-2007-09-11
..\logs\access-2007-09-05  ..\logs\access-2007-09-12

$ rm ..\logs*
..logs*: No such file or directory

You will realise that you are not able to remove them using 'rm' command. However, you can remove them based on their corresponding i-node number. In 'find', you can specify the i-node number with '-inum'. To remove it, simply include '-exec rm' in 'find'. The down side is you need to do it one at a time, or feed the i-node in a loop.

$ ls -ai1
     41286 .
        25 ..
     41287 ..\logs\access-2007-09-01
     41288 ..\logs\access-2007-09-02
     41289 ..\logs\access-2007-09-03
     41290 ..\logs\access-2007-09-04
     41291 ..\logs\access-2007-09-05
     41292 ..\logs\access-2007-09-06
     41293 ..\logs\access-2007-09-07
     41294 ..\logs\access-2007-09-08
     41295 ..\logs\access-2007-09-09
     41296 ..\logs\access-2007-09-10
     41297 ..\logs\access-2007-09-11
     41298 ..\logs\access-2007-09-12

$ find . -inum 41287 -exec /bin/rm -i {} \;
rm: remove ./..\logs\access-2007-09-01 (yes/no)?

$ for i in `ls -ai1 | awk '/logs/ {print $1}'`
do
  find . -inum $i -exec rm -i {} \;
done

So, can we use 'find' to locate these files and have them removed in a one-liner? The trick is to be able to pass the pattern (\\, two backslashes) to 'find' so that the escape meaning of a '\\' will be interpreted as '\'. If you use doube quote (") syntax in 'find', you will have to have four backslashes to represent a backslash inside. If you are using single quote syntax, you will need two backslashes. Make sure you include '-i' in 'rm' to prompt you before removal, unless you are sure what are doing.

$ find . -name "..\logs\*"

$ find . -name "..\\logs\\*"

$ find . -name "..\\\\logs\\\\*"
./..\logs\access-2007-09-01
./..\logs\access-2007-09-02
./..\logs\access-2007-09-03
./..\logs\access-2007-09-04
./..\logs\access-2007-09-05
./..\logs\access-2007-09-06
./..\logs\access-2007-09-07
./..\logs\access-2007-09-08
./..\logs\access-2007-09-09
./..\logs\access-2007-09-10
./..\logs\access-2007-09-11
./..\logs\access-2007-09-12

$ find . -name '..\\logs\\*'
./..\logs\access-2007-09-01
./..\logs\access-2007-09-02
./..\logs\access-2007-09-03
./..\logs\access-2007-09-04
./..\logs\access-2007-09-05
./..\logs\access-2007-09-06
./..\logs\access-2007-09-07
./..\logs\access-2007-09-08
./..\logs\access-2007-09-09
./..\logs\access-2007-09-10
./..\logs\access-2007-09-11
./..\logs\access-2007-09-12


$ find . -name '..\\logs\\*' -exec /bin/rm -i {} \;
rm: remove ./..\logs\access-2007-09-01 (yes/no)?
rm: remove ./..\logs\access-2007-09-02 (yes/no)?
rm: remove ./..\logs\access-2007-09-03 (yes/no)?
rm: remove ./..\logs\access-2007-09-04 (yes/no)?
rm: remove ./..\logs\access-2007-09-05 (yes/no)?
rm: remove ./..\logs\access-2007-09-06 (yes/no)?
rm: remove ./..\logs\access-2007-09-07 (yes/no)?
rm: remove ./..\logs\access-2007-09-08 (yes/no)?
rm: remove ./..\logs\access-2007-09-09 (yes/no)?
rm: remove ./..\logs\access-2007-09-10 (yes/no)?
rm: remove ./..\logs\access-2007-09-11 (yes/no)?
rm: remove ./..\logs\access-2007-09-12 (yes/no)?

Labels:

0 Comments:

Post a Comment

<< Home