1

I want to make script that searches,shows and delete for names ending in "*". My command:

echo rm `find -name "*[*]"`

Command works ,but I create file: something and something(ended star) Now after write command it, shows me : rm something(ended star) and similar file "something" Why?

  • 1
    The output of `find -name "*[*]"` is `./something*`. So your command is like calling `rm ./something*`, and the bash will replace the `./something*` by a list of all files starting with `something`. – Stefan Hamcke Dec 17 '18 at 22:51
  • Thanks for advice but how can I save a star as the character on which the file name ends? – MarioFalcon Dec 17 '18 at 22:54
  • If you want to prevent the expansion of the glob, use double quotes `echo rm "$(find -name "*[*]")"` Note that I've replaced backticks with $() for 2 reasons: 1) it's difficult to put backticks in a comment, and 2) backticks have have been superseded by `$()` for several decades. Stop using them! – William Pursell Dec 17 '18 at 23:10

2 Answers2

1

As Stefan Hamcke states in comments, this is because the wildcard (*) from find's result ("something*") is passed as argument to echo and ends up being expanded again, resulting in the final output having both something and something*.

Do this instead:

find . -name "*[*]" -exec echo rm {} +

Output:

rm ./something*

You can also achieve the same with the expression "*\*" in find.

Vasan
  • 4,810
  • 4
  • 20
  • 39
  • This time, my output after entering your command is: rm rm ./something ./something* – MarioFalcon Dec 17 '18 at 23:11
  • That shouldn't be possible. What do you get if you just run find, without the `-exec` part ? – Vasan Dec 17 '18 at 23:13
  • the same as before – MarioFalcon Dec 17 '18 at 23:14
  • Can you do a `ls` in your directory and paste the output or a screenshot in your question? – Vasan Dec 17 '18 at 23:18
  • mariusz@mariusz-VirtualBox:~/folder$ ls about something 'something*' mariusz@mariusz-VirtualBox:~/folder$ echo rm `find . -name "*[*]" -exec echo rm {} +` rm rm ./something ./something* mariusz@mariusz-VirtualBox:~/folder$ – MarioFalcon Dec 17 '18 at 23:34
  • Ok, looks like you're trying to combine your command with mine. That wouldn't work. You should run just my command on its own (starting from `find` till the +). – Vasan Dec 17 '18 at 23:35
  • How I can change this command to for? I try write this but it doesnt work: for k in *[*]; do find . -name "$k" -exec echo rm {} +; done; – MarioFalcon Dec 17 '18 at 23:51
  • @MarioFalcon I'll need more details on what you're trying to do. This command already finds all files with name ending with `*`. Why do you need this in a loop? – Vasan Dec 17 '18 at 23:54
  • I need apply this command on other serwer. When I enter this command there is no message and no effects. – MarioFalcon Dec 18 '18 at 08:44
  • If by "other serwer" you mean that you connect over `ssh` to another server with the command as an argument to `ssh`, you need additional quoting because `ssh` basically causes another round of shell evaluation of the command to take place. – tripleee Dec 18 '18 at 08:54
0

The bug is that you do not quote the argument to echo. Here is a trivial fix:

echo "rm $(find -name "*[*]")"

This is not entirely a minimal fix because I also replaced the obsolescent `backtick` syntax with the modern, recommended $(command substitution) syntax.

Without quotes, the string returned from the command substition gets evaluated by the shell for token splitting and wildcard expansion. For details, see When to wrap quotes around a shell variable?

tripleee
  • 175,061
  • 34
  • 275
  • 318