Reputation: 7
I've got tree of folders like:
00 -- 0
-- 1
...
-- 9
...
99 -- 0
-- 1
...
-- 9
In every folder I have .ini files with some kind od text.
How can I remove files which got #
at beginning of second line?
I tried to use:
for i in {00..99}; do for b in {0..9}; do grep -LZ -- # *.ini | xargs
-r0 rm; done; done
but it didn't works. I wonder about using sed
and awk
to do it, but i don't know how.
Upvotes: 0
Views: 35
Reputation: 189327
With a recent enough Awk and GNU find
you can do
awk 'FNR==2 { if ($0 ~ /^#/) printf "%s\0", FILENAME; nextfile }' [0-9][0-9]/[0-9]/*.ini |
xargs -r0 echo rm
The nextfile
statement is a POSIX extension but might not be present in very old Awk implementations. If your files are small, maybe just take out the nextfile
and live with the minor inefficiency that we read through the end of each file even though we only really need to examine the second line.
The -0
option to xargs
is a GNU extension. If your file names are guaranteed to not contain newlines, you can probably get away with
awk 'FNR==2 { if ($0 ~ /^#/) print FILENAME; nextfile }' [0-9][0-9]/[0-9]/*.ini |
xargs -r echo rm
Finally, remove the echo
to actually remove the files it prints.
In some more detail, Awk processes each input file one line at a time, and evaluates the script on each separately. The built-in variable FNR
is set to the current line number within the file, and FILENAME
is the current file's name. The variable $0
contains the entire line, and we check whether it matches the regular expression ^#
(beginning of line, immediately followed by a literal #
character); if so, we print the FILENAME
(otherwise, no output for this file). The nextfile
command closes the current file and skips directly to the first input line of the next file in the argument list (or stops processing if no file names remain to be processed).
If you have a lot of matching files, you can't use a wildcard like that (you get "argument list too long"); if so, maybe simply revert back to the loop you had.
The immediate error in your attempt is that you need quotes around #
(otherwise, it marks the rest of the line as a comment); but of course, your grep
looks for that character anywhere in the file, and you didn't specify the path for the file to examine. With the immediate errors fixed, that would be
# Don't use, still broken
for i in stuff; do
for b in more stuff; do
grep -LZ '#' "$i/$b"/*.ini
done
done |
# or simply grep -LZ '#' [0-9][0-9]/[0-9]/*.ini
xargs -r0 echo rm
but again, you can't easily fix this to only look at the second line of each file. (Notice also how I run the final xargs
outside the final done
.)
Upvotes: 1