The problem
In the current working directory I have several (very many) folders and some of them have lots (like 100,000+) of files inside.
My goal is getting just the folder with 10,000+ files and delete folderName10001.ext
and above (where folderName
is the actual name of the containing folder and ext
is a whatever extension).
Approach taken
I am trying to print nameFolder numberOfFiles
with bash
.
find . -maxdepth 1 -type d -name 'acer' -exec sh -c "echo {}; ls {} | wc -l" \;
This works just fine (for the sample folder acer
), but the output is
./acer
6058
I would like to have 1-line output per folder
find . -maxdepth 1 -type d -name 'acer' -exec sh -c "echo {} `ls {} | wc -l`" \;
says ls: cannot access {}: No such file or directory
.
Questions
- How can I get to display in one line
nameFolder numberOfFiles
? - Is there an easier way to delete every file
folderName/folderName#.ext
, with#
>10000
?
Question 2
Some more details may help understand what's going on.
I have a folder with the following tree
.
├── a
│ ├── a1.ext
│ ├── a2.ext
│ ├── a3.ext
│ └── a4.ext
├── b
│ ├── b1.ext
│ ├── b2.ext
│ ├── b3.ext
│ └── b4.ext
└── c
├── c1.ext
├── c2.ext
├── c3.ext
└── c4.ext
I'd like to remove every file with a number greater than 2
. (In my specific case the threshold is set to 10000
.)
Answer 1
It's all about who interprets what (thanks to @Bratchley for the advise in the comments).
Since I'm typing into bash
, bash
gets first to interpret what I type.
If I want bash
to send to find
's bash
a backtick, then I need to escape it.
find . -maxdepth 1 -type d -name 'acer' -exec sh -c "echo {} \`ls {} | wc -l;\`" \;
which gives me
./acer 6058
@Barmar points out that single- and double-quotes behaves differently, and therefore
find . -maxdepth 1 -type d -name 'acer' -exec sh -c 'echo {} `ls {} | wc -l`' \;
would work just fine (note "
replaced with '
).
Answer 2
This has been provided by Walter A, and it is the accepted answer for this question.
More errors (a couple of examples follows)...
black: 390120
./clean.sh: line 6: /bin/ls: Argument list too long
rm: missing operand
Try 'rm --help' for more information.
leather: 118240
./clean.sh: line 6: /bin/ls: Argument list too long
rm: missing operand
Try 'rm --help' for more information.
OK, I've fixed it with
ls -d */ | cut -d/ -f1 | while read dir; do
COUNT=$(ls $dir | wc -l);
if [ ${COUNT} -gt 10000 ]; then
echo "$dir: ${COUNT}" ;
for i in `seq 10001 ${COUNT}`; do
rm ${dir}/${dir}${i}.*
done
fi
done
echo
the-n
option.find . -maxdepth 1 -type d -exec sh -c "echo {} \$(ls {} | wc -l)" \;
work for you?$(...)
but it was giving be the same problem of the backtick. What does exactly the ` \ ` do? I mean, the\$(...)
works like a charm.bash
is executed first bybash
itself, and then it is sent to thefind
'sbash
. OK, a bit confusing, but I got it.