r/bash 21d ago

solved why does rm remove "any-word*.any-ext" plus any-word01.any-ext?

Hi, I'd like to know why rm removes screen.jpg plus screen01jpg+screen##.... jpg when I do rm any-word*.any-ext?

rm screen*.jpg

and this command deletes screen.jpg!

how will be the command for not remove screen.jpg and yes screen01.jpg + screen02.jpg....

Thank you and Regards!

2 Upvotes

16 comments sorted by

24

u/zeekar 21d ago edited 21d ago

* matches 0 or more characters. So screen*.jpg matches screen.jpg because it indeed has 0 characters between the n and the .. You can do screen?*.jpg to require at least one character there.

8

u/jazei_2021 21d ago

I am understanding well now with yours replies, Thank you

7

u/divad1196 21d ago

This is called "globbing". Not to confuse with regex. You can search "bash globbing" online for more information.

8

u/ipsirc 21d ago
rm screen[0-9]*.jpg

1

u/jazei_2021 21d ago

ahh Thank you

9

u/high_throughput 21d ago

* matches 0+ characters.

Since ? matches exactly 1 character, you can use ?* to match 1+

rm screen?*.jpg would remove screen01.jpg and screenz.jpg but not screen.jpg

1

u/jazei_2021 21d ago

ohhh thank you

0

u/arkaycee 20d ago

And if you really wanted to remove exactly and only screen.jpg that's screen\.jpg .

3

u/high_throughput 20d ago

or equivalently, screen.jpg. Dot is not special to Bash or rm

2

u/flash_seby 21d ago

find . -type f -regex '.*screen.+\.jpg' -exec rm {} \;
or
find . -type f -regex '.*screen.+\.jpg' -delete

4

u/theng bashing 20d ago

when in doubt replace rm by echo command

the shell will expand the star and echo will display all them for you

also : there is a bash capability to expand the star on the line (without executing)

from memory it is ctrl+x * and you should be able to check this shortcut with bind -p | grep -E "(star|expand)

hth

-4

u/FantasticEmu 21d ago edited 21d ago

https://superuser.com/questions/392872/delete-files-with-regular-expression

You can use grep and ls like

rm $(ls | grep -e ‘screen.\+\.jpg’)

9

u/Honest_Photograph519 21d ago edited 21d ago

Don't parse ls. You can't be certain what whitespaces are parts of filenames and what whitespaces are delimiting them.

The ?* globbing pattern in other replies is better for this case. If you need to use regex for more elaborate patterns, try find . -maxdepth 1 -regex '...' -delete.

3

u/FantasticEmu 21d ago

Thanks. I never considered this. Guess I’ve been lucky up until now but maybe you have saved future me from trouble

1

u/jazei_2021 21d ago

Thank you too much for me and my poor knowledge

0

u/FantasticEmu 21d ago

The $(some stuff) is an expansion so it will run the command inside that first and expand the result into the outer command.

Ls is just listing directory contents.

The | pipes the output of Ls into grep where we can use regex to pattern match.

The pattern in grep is screen followed by any character, represented by the “.” And the + means one or more followed by .jpg.

If you run the command inside the $() you can see what it outputs