How to delete files filtered out by awk
Solution 1
You have two bugs:
You are comparing for a size that contains
46
; you want it to be equal to 46.You are printing the entire line, when you want only the filename.
And an additional issue: what is the point of -ltr
to sort the ls
output when you aren't using the sort order?
You want to do something like
ls -l | awk '$5 == "46" {print $9}' | xargs rm
Except you don't want to do that, because while it might be safe at the moment, parsing ls
output is unreliable. Use an appropriate tool such as
find . -maxdepth 1 -size 46c -delete # requires GNU find
(Doing this portably is more annoying, since POSIX find
doesn't have -maxdepth
or -size
that operates in units other than blocks. Better to write a script in a Perl/Python/Ruby/etc. that can use a proper directory scan that won't get in trouble with special characters in filenames.)
Solution 2
In zsh, to remove all files of size 26 in the current directory (first line) or the current directory and its subdirectories (second line), use the L
glob qualifier:
rm *(L26)
rm **/*(L26)
With GNU or FreeBSD/NetBSD/OSX find:
find . -name . -o -type d -prune -o -type f -size 26c -exec rm {} +
find . -type f -size 26c -exec rm {} +
Portably:
find . -name . -o -type d -prune -o -type f -exec sh -c '[ $(wc -c <"$0") -eq 26 ] && rm -- "$0"' {} \;
find . -type f -exec sh -c '[ $(wc -c <"$0") -eq 26 ] && rm -- "$0"' {} \;
Related videos on Youtube
Preeyah
Professional Software Testing Engineer specializing in automation with Open Source tools. Interested in: Test automation: Selenium, BDD, Cucumber Programming: Java, Python, Spring Data scraping Audio: recording/mixing
Updated on September 18, 2022Comments
-
Preeyah over 1 year
I have the following files in a directory:
-rw-r--r-- 1 smsc sys 46 Apr 22 12:09 bills.50.1.3G.MO.X.20120422120453.Z -rw-r--r-- 1 smsc sys 28 Apr 22 12:15 bills.50.1.3G.MO.X.20120422120953.Z -rw-r--r-- 1 smsc sys 46 Apr 22 12:20 bills.50.1.3G.MO.X.20120422121453.Z -rw-r--r-- 1 smsc sys 46 Apr 22 12:25 bills.50.1.3G.MO.X.20120422121953.Z
Where the fifth column is the file's size. I wish to delete all files which size is 46. In order to filter out these files I used the following command:
ls -ltr | awk '$5 ~ /46/ {print $0}'
Which works fine. But now I want to delete all files which were filtered out, so I add the following to the above command:
ls -ltr | awk '$5 ~ /46/ {print $0}' | xargs rm
However it gives me the following error:
rm: invalid option -- w
It seems that I have to use
find
overls
so I will get the output in the below format:./bills.50.1.3G.MO.X.20120421050453.Z ./bills.50.1.3G.MO.X.20120421154953.Z ./bills.50.1.3G.MO.X.20120419133452.Z
But then I have no way to filter the files by its parameters. How this task could be done?
-
sr_ about 12 yearsBtw,
find
could also do this, i.e. something likefind . -maxdepth 1 -size 46c -delete
(at least GNU find can) -
Preeyah about 12 years@sr_ That's an interesting option. I will keep that in mind. Thanks!
-
jw013 about 12 yearsPlease don't parse
ls
output. @sr_ You should post that as an answer. -
jw013 about 12 years@EugeneS ... except sr_ has already shown you exactly how to do this safely with
find
. Why don't you just use the suggested command? It is never necessary to usels
for manipulating files (at least I have yet to run into such a situation) sincefind
and shell globbing cover nearly all cases.
-
-
Preeyah about 12 yearsThank you for your answer and mentioning ALL the bugs! You're absolutely right, it works fine now. Regarding the
-ltr
, I guess it's just a bad habit. -
geekosaur about 12 yearsAlso note the comment above about parsing
ls
output, which I let pass; it is really not a good idea, due to the possibility of spaces and other special characters in filenames. -
Preeyah about 12 yearsI know that but I couldn't think about a way to avoid this. If you can edit your answer and describe a way to perform this task without using
ls
I will be grateful. Thanks again! -
jippie about 12 yearsI would advise using
$NF
(always referring to the last field) instead of$9
. -
geekosaur about 12 years@jippie, that's still not going to work if there's whitespace in the name.