Reputation: 45
Naidim answered this question: How to replace spaces in file names using a bash script
This was the only answer I could get to work for me, but I don't understand what I am looking at.
for f in *\ *; do mv "$f" "${f// /_}"; done
Upvotes: 0
Views: 72
Reputation: 126418
Breaking it down:
*\ *
is a filename glob pattern. This expands to all the files in the current directory that have spaces in them. Normally spaces separate arguments to commands (which happens before glob expansion), but having a \
escape before it makes it a literal space and thus part of the glob pattern.
for f in *\ *
; is a for loop, looping over all the things after in
-- in this case the list of files from the glob expansion. The variable f
will be set to each filename in turn and the code up to the done
command will be executed for each filename.
"$f"
is a variable expansion. Variable expansion comes before word splitting (unlike glob expansion), so the quotes are necessary to keep the spaces in the filename togther as part of a single argument and not split into multiple arguments.
${f// /_}
is a variable expansion with substitution. The initial //
means the pattern is applied repeated to the variable contents, not just once. The space between the / /
is the pattern to search for, and the final _
is the replacement, so all spaces in f
(the filename from the loop) will be replaced with underscores.
Upvotes: 5
Reputation: 43039
You may want to read more about globbing and Bash parameter expansion to understand this code.
*\ *
=> is the glob which matches all entries in the current directory that have one more spaces in them${f// /_}
=> Bash parameter expansion that replaces spaces with a -
in the variable f
(1:1 replacement)So, the loop picks up all entries in current directory (files, directories, symlinks, etc.) that have a space in their name and renames them to a name that uses _
in place of spaces.
Upvotes: 1
Reputation: 603
The confusing expansion is a parameter substitution. The form ${foo/bar/baz}
is used to search for the string bar
inside $foo
and replace it with baz
. If bar
starts with a /
(as is the case in your loop), then all occurrences of bar
are replaced with baz
. For more information you can read the Parameter Expansion
heading in the bash manpage.
Upvotes: 0