1

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

$ cp 'A long filen* ./short_filename

M Ice
  • 13
  • 3

3 Answers3

6

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
pLumo
  • 22,565
  • 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
2

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
jesse_b
  • 37,005
  • 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
2

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.
derobert
  • 109,670