In UNIX it's uncommon to have files with spaces but it can happen. Consider a situation wherein I have a couple of space separated files and I'd like to remove some of them.
[root@pbox test]# ls -l
total 0
drwxr-xr-x. 2 root root 6 Aug 30 14:25 abc
drwxr-xr-x. 2 root root 6 Aug 30 14:25 def
-rw-r--r--. 1 root root 0 Aug 30 14:17 my file 1
-rw-r--r--. 1 root root 0 Aug 30 14:17 my file 2
-rw-r--r--. 1 root root 0 Aug 30 14:17 my file 3
-rw-r--r--. 1 root root 0 Nov 7 2017 my file 4
-rw-r--r--. 1 root root 0 Nov 7 2020 my file 5
-rw-r--r--. 1 root root 0 Nov 7 2017 my file 6
-rw-r--r--. 1 root root 0 Aug 30 14:24 my file 7
I'd like to remove files modified in the month of August.
[root@pbox test]# ls -l |grep -i ^-|grep -i Aug
-rw-r--r--. 1 root root 0 Aug 30 14:17 my file 1
-rw-r--r--. 1 root root 0 Aug 30 14:17 my file 2
-rw-r--r--. 1 root root 0 Aug 30 14:17 my file 3
-rw-r--r--. 1 root root 0 Aug 30 14:24 my file 7
Now if I try to run the for loop to iterate over the required files I get an unexpected result because of the spaces:
[root@pbox test]# for i in $(ls -l |grep -i ^-|grep -i Aug| awk '{print $9, $10, $11}') ; do echo "$file to remove is $i" ; done
to remove is my
to remove is file
to remove is 1
to remove is my
to remove is file
to remove is 2
to remove is my
to remove is file
to remove is 3
to remove is my
to remove is file
to remove is 7
[root@pbox test]# ls -l
total 0
drwxr-xr-x. 2 root root 6 Aug 30 14:25 abc
drwxr-xr-x. 2 root root 6 Aug 30 14:25 def
-rw-r--r--. 1 root root 0 Aug 30 14:17 my file 1
-rw-r--r--. 1 root root 0 Aug 30 14:17 my file 2
-rw-r--r--. 1 root root 0 Aug 30 14:17 my file 3
-rw-r--r--. 1 root root 0 Nov 7 2017 my file 4
-rw-r--r--. 1 root root 0 Nov 7 2020 my file 5
-rw-r--r--. 1 root root 0 Nov 7 2017 my file 6
-rw-r--r--. 1 root root 0 Aug 30 14:24 my file 7
I'd like to remove files modified in the month of August.
[root@pbox test]# ls -l |grep -i ^-|grep -i Aug
-rw-r--r--. 1 root root 0 Aug 30 14:17 my file 1
-rw-r--r--. 1 root root 0 Aug 30 14:17 my file 2
-rw-r--r--. 1 root root 0 Aug 30 14:17 my file 3
-rw-r--r--. 1 root root 0 Aug 30 14:24 my file 7
Now if I try to run the for loop to iterate over the required files I get an unexpected result because of the spaces:
[root@pbox test]# for i in $(ls -l |grep -i ^-|grep -i Aug| awk '{print $9, $10, $11}') ; do echo "$file to remove is $i" ; done
to remove is my
to remove is file
to remove is 1
to remove is my
to remove is file
to remove is 2
to remove is my
to remove is file
to remove is 3
to remove is my
to remove is file
to remove is 7
This is because the default input field separator is a space character so whenever the for loop sees a space it treats the following string as a new field.
To fix this we'll modify our input field separator by changing the value of the IFS variable.
[root@pbox test]# IFS=$'\n'
[root@pbox test]# for i in $(ls -l |grep -i ^-|grep -i Aug| awk '{print $9, $10, $11}') ; do echo "$file to remove is $i" ; done
to remove is my file 1
to remove is my file 2
to remove is my file 3
to remove is my file 7
[root@pbox test]#
Now instead of doing an echo if we'd like to remove the files we could simply type the following:
[root@pbox test]# for i in $(ls -l |grep -i ^-|grep -i Aug| awk '{print $9, $10, $11}') ; do rm $i ; done
rm: remove regular empty file ‘my file 1’? y
rm: remove regular empty file ‘my file 2’? y
rm: remove regular empty file ‘my file 3’? y
rm: remove regular empty file ‘my file 7’? y
And the files are now gone.
[root@pbox test]# ls -ltr
total 0
drwxr-xr-x. 2 root root 6 Aug 30 14:25 def
drwxr-xr-x. 2 root root 6 Aug 30 14:25 abc
-rw-r--r--. 1 root root 0 Nov 7 2017 my file 4
-rw-r--r--. 1 root root 0 Nov 7 2017 my file 6
-rw-r--r--. 1 root root 0 Nov 7 2020 my file 5
No comments:
Post a Comment