Renaming the recent directory with spaces in its name

I am trying to rename the recent directory with spaces in its name.

$ mkdir "foo bar"
foo bar
$ ls -c | head -1
$ mv $(ls -c | head -1) foobar

Getting the following error:

mv: target 'foobar' is not a directory

Solution 1:

Your immediate problem is that the command substitution is unquoted, leaving the mv command with:

mv foo bar foobar

... where mv is expecting "foobar" to be a destination directory for the (presumably non-existent) files "foo" and "bar". You don't want to solve this problem by putting quotes around the command substitution because parsing the output of ls is a headache you don't want to deal with. Consider:

mkdir $'newline\nhere'

... which ls -c | head -1 reports as simply "newline" instead of the proper name.

Of course, to solve the immediate problem, simply quote the directory the same way you did when you created it:

mv "foo bar" foobar

If there's only one mistakenly-named directory and you want to rename it to something specific, you could find a matching wildcard and then manually rename it. Test with ls -d *wildcard* until you get just the one errant directory and then run:

mv *that-wildcard* the-new-name

If the mistaken directory name is too difficult to pin down with a wildcard, you could use a shell loop to rename every directory that has spaces in it:

for dir in *\ */
do
  [ -e "${dir// /}" ] && continue
  mv -- "${dir}" "${dir// /}"
done

This generates a wildcard-expanded list of subdirectories that have a space in them; the directory restriction is achieved with the trailing / in the wildcard. Each of those directories is then tested to see if the new name already exists; if so, we skip it to avoid clobbering files or moving directories underneath others. If we're all clear, then mv will rename the directory using parameter expansion to replace every space with nothing.

Another alternative would be to use the zsh shell's feature where it can sort ("order") filename expansions by modification time. You could rename the most recently modified directory that has spaces in it using:

zsh -c 'mv -- *\ *(/om[1]) newdir'

This uses the same "has a space in it" wildcard from before, but adds "Glob Qualifiers" in parenthesis. Those are:

  • / -- restrict matches to directories
  • om -- order the matches by modification time (newest first)

We then select the first entry in that list with [1] as the source directory to rename to "newdir".