I'm trying escape characters like \' but it doesn't work.

$ cp 'A long filen* ./short_filename

  • 3
    Does the filename include a ' or did you forget to close the quotes? – jesse_b Jan 11 '19 at 14:04
  • yes, it does. That line doesn't work. – M Ice Jan 11 '19 at 14:06
  • ...What? What is the filename? – jesse_b Jan 11 '19 at 14:07
  • 'Really long filename.mp4' – M Ice Jan 11 '19 at 14:09
  • 3
    Sure that it's including the quotes or is it due to the new output from ls? See unix.stackexchange.com/questions/258679/… – pLumo Jan 11 '19 at 14:26

Your file does not contain quotes, it is a new output behavior of ls.

See: Why is 'ls' suddenly wrapping items with spaces in single quotes?

You can use

cp "A long file n"* short_filename

The * must be outside the quotes

or escape all spaces (and other special characters like \, ; or |, etc.)

cp A\ long\ file\ n* short_filename
  • I chose this answer because it tells about ls behaviour and the two examples work for me. I upvoted the other answer but those votes are recorded because of my reputation. – M Ice Jan 11 '19 at 14:52

GNU ls, at least, can also tell you how to quote something. In more recent versions its on by default, but even going back years you can do something like:

$ ls --quoting-style=shell
"'A long filename.mp4'"

There are other quoting styles available too; see the ls manpage.

You can also do something with printf (at least in bash):

$ printf '%q\n' *
\'A\ long\ filename.mp4\'

The %q means to print the argument out quoted (followed by \n, a newline), and * matches all the file names. So this is a sort-of-ls using printf.

Then after that, you just have to figure out how to add in your *. It needs to not be quoted, so in the two styles it'd be:

"'A long file"*    # we've just cut a ""-quoted string short.
\'A\ long\ file*   # that's just escapes, so cut it short.

If the filename includes single quotes you can escape them with \ or double quotes. You also have to escape the spaces though:

$ touch \'A\ long\ filename\'
$ ll
total 1
-rw-rw-r-- 1 jesse jesse 0 Jan 11 14:09 'A long filename'

You cannot escape the * for it to glob though so you must leave it outside the quotes:

$ ls -l \'A\ long\ file*
-rw-rw-r-- 1 jesse jesse 0 Jan 11 14:09 'A long filename'
$ ls -l "'A long file"*
-rw-rw-r-- 1 jesse jesse 0 Jan 11 14:09 'A long filename'

$ cp "'A long file"* ./short_file
$ ll
total 1
-rw-rw-r-- 1 jesse jesse 0 Jan 11 14:09 'A long filename'
-rw-rw-r-- 1 jesse jesse 0 Jan 11 14:11 short_file
  • 1
    Your examples are all with the file name literally being 'A long filename', including the single quotes. I suspect OP may just have A long filename though, without the quotes. Might want to give an example if that's the case. – derobert Jan 11 '19 at 14:16
  • @derobert: OP said the filename contains single quotes – jesse_b Jan 11 '19 at 14:17
  • 1
    You're right, I misread that comment. Sorry for the noise. – derobert Jan 11 '19 at 14:19
  • No worries, seems like it shouldn't be part of the actual filename but I have seen worse filenames :p – jesse_b Jan 11 '19 at 14:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.