There are 5 million files with file name from file0000001.dat to file9999999.dat, in the same directory, and with some other files with random names.
I was trying to remove all the files from file0000001.dat to file9999999.dat at the same time.
If use 'rm file???????.dat', trying to remove them at once, then there was an error output.
If instead use 'rm file1??????.dat' , trying to remove 10% of them at a time, then the shell did not response in several hours and had to kill the process.
Does any expert of file system can help? Or is it possible to do that by any chance?
What version of HP-UX?
What type of filesystem on what physical disc arrangement?
Is the filesystem mirrored?
Is NFS or anything slow involved?
What is the approximate total size of the files to be deleted?
What is the size of the directory file and how many inodes?
ls -lad /directory_name
df -i /directory_name
What was the "error output" mentioned above?
Are there any subdirectories under the directory containing these files?
i.e. Does this "find" command find all the files without unwanted hits and without finding files we don't want and without pointless searching?
find /directory_tree -type f -name file\?\?\?\?\?\?\?\.dat -print
Let it run. Deleting that many files will take a very long time. It probably did delete some of them. Do "ls file1??????.dat | wc -l" to count how many are left.
That is adding half a million fork() calls to a procedure that is already painfully long. I must advise against that. Once an hour or so he can count the remaining files using the command I gave. (Put the delete in the baxkground or use a second window.)
That'd probably die with 'too many arguments', too, just like the OP did. The answer to 'too many arguments' is not to cram the too many arguments into ls instead, the answer is to not use that many arguments because you cannot cram an unlimited number in there. On some OSes the limit is surprisingly small.
xargs could be used to cut the workload in pieces, but the trouble with (non-GNU) xargs is that it does not work for file names with spaces in the name, since the input delimiter cannot be specified.
But how about something like this
ls | grep 'file.......\.dat' |
( IFS="
"
set --
i=0
while read file
do
set -- $@ $file
if [ $((i+=1)) -ge 32 ]; then
rm $@
i=0
set --
fi
done
rm $@
)
The number 32 could be changed to 16 or some other number..
This should probably work too:
( IFS="
"
set --
i=0
for f in file???????.dat
do
set -- $@ "$f"
if [ $((i+=1)) -ge 32 ]; then
ls $@
i=0
set --
fi
done
ls $@
)
The above code is not suitable for 5 million files for three reasons:
1) The expanded "ls" command will still be too long.
2) The "ls" program sorts the filenames to alphabetical order - a massive overhead in this circumstance.
3) It does not correctly deal with filenames containing space characters.