Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Delete all files with the same name as the ones that end in `.part`

+3
−0

I want to find all files under the current directory that end in .part and delete them, along with all files with the same name even the ones with different extension.

Is this correct?

find . -name '*.part' -exec sh -c 'base="$(basename "$1" .part)"; find . -name "$base*" -delete' sh {} \;
Why does this post require moderator attention?
You might want to add some details to your flag.
Why should this post be closed?

0 comment threads

1 answer

+3
−0

It is incorrect for several reasons.

You did not restrict Find's depth

It will thus descend into subdirectories and delete matching files there too.

Easily solvable by adding -maxdepth 1 to each Find.

File names containing glob characters

This is an edge case scenario.

Consider this structure:

.
├── abc
├── abc.part
├── cde
└── c*e.part

The outermost Find will find

  • abc.part, so base=abc and the innermost Find looks for files matching the glob abc*, which matches the abc file. Good.
  • c*e.part, so base=c*e and the innermost Find looks for files matching the glob c*e*, which matches the cde file. Bad, because cde does not contain c*e.

File names with extra characters

If you have abcde and abc.part files, the former will be deleted because it matches abc* as should be clear from the previous case discussion.

This particular problem would be easily fixed by changing $base* -> $base.*.

Solutions

You only want to operate in the current directory, so why not

for f in *.part; do
    rm "${f%.part}."*
done

Here it is crucial not to quote the *, because we want it to act as a glob (and not literally).

${f%suffix} is a special form of parameter expansion available in all POSIX shells. It means "remove suffix from the expansion of f". It looks cleaner than Basename and doesn't spawn an extra process.

For something more along the lines you suggested,

find . -maxdepth 1 -name '*.part' -exec sh -c 'rm "$(basename "$1" .part)".*' sh {} \;

But it looks considerably convoluted and -maxdepth 1 is not a POSIX specified option to Find, so you are also sacrificing portability. (It is possible to write the POSIX equivalent of -maxdepth 1 but it adds obscurity.)

Why does this post require moderator attention?
You might want to add some details to your flag.

1 comment thread

I think not restricting depth was intentional (2 comments)

Sign up to answer this question »

This community is part of the Codidact network. We have other communities too — take a look!

You can also join us in chat!

Want to advertise this community? Use our templates!

Like what we're doing? Support us! Donate