How can I recursively delete all files ending in .foo
which have a sibling file of the same name but ending in .bar
? For example, consider the following directory tree:
.
├── dir
│ ├── dir
│ │ ├── file4.bar
│ │ ├── file4.foo
│ │ └── file5.foo
│ ├── file2.foo
│ ├── file3.bar
│ └── file3.foo
├── file1.bar
└── file1.foo
In this example file.foo
, file3.foo
, and file4.foo
would be deleted since there are sibling file{1,3,4}.bar
files. file{2,5}.foo
should be left alone leaving this result:
.
├── dir
│ ├── dir
│ │ ├── file4.bar
│ │ └── file5.foo
│ ├── file2.foo
│ ├── file3.bar
└── file1.bar
Remember to first take a backup before you try this find
and rm
command.
Use this find
:
find . -name "*.foo" -execdir bash -c '[[ -f "${1%.*}.bar" ]] && rm "$1"' - '{}' \;
while IFS= read -r FILE; do
rm -f "${FILE%.bar}".foo
done < <(exec find -type f -name '*.bar')
Or
find -type f -name '*.bar' | sed -e 's|.bar$|.foo|' | xargs rm -f
In bash
4.0 and later, and in zsh
:
shopt -s globstar # Only needed by bash
for f in **/*.foo; do
[[ -f ${f%.foo}.bar ]] && rm ./"$f"
done
In zsh
, you can define a selective pattern that matches files ending in .foo
only if there is a corresponding .bar
file, so that rm
is invoked only once, rather than once per file.
rm ./**/*.foo(e:'[[ -f ${REPLY%.foo}.bar ]]':)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With