Skip to main content
question was about copying, not removing. add example for large number of files
Source Link

ls has some switches (like --quote-name, --escape, --literal) for dealing with unprintable characters, but in this case it seems the character is "printable" but not "typeable" (at least on my keyboard!), so none of these switches seem to help.

Therefore, as a general "brute force" approach to get rid of files with any characters in their names, you can do this:

$ /bin/ls -1A|cat -n # list all files (except . and ..), 1 per line, add line numbers 1 ♫ 2 f1.txt 3 f2.txt 

Find the line containing the offending file. Quite likely it will be the 1st line, but let's say it's the 5th. Print line 5 and hex encode it:

$ /bin/ls -1A|sed -n 5p|xxd -g 1 0000000: e2 99 ab 0a .... 

Ignoring the 0a (newline) character, construct an escape string, and use the -e option of echo to translate the escapes:

$ echo -e '\xe2\x99\xab' ♫ 

Now you can copy/move/delete it like this:

$ cp -vi $(echo -e '\xe2\x99\xab') better_name ‘♫’ -> ‘better_name’ 

Also, if you're not confined to using shell script, you could do it in Python like this:

$ python >>> import os >>> os.listdir('.') [ ..., '\xe2\x99\xab', ... ] >>> print '\xe2\x99\xab' ♫ >>> osimport shutil >>> shutil.renamecopy('\xe2\x99\xab', 'better_name') 

Using this approach, you can process many files, you just have to write the logic for selecting the correct files, and renaming them without clobbering, etc:

for f in os.listdir('.'): if not f.isalnum(): newname = generate_newname(f) if not os.path.exists(newname): shutil.copy(f, newname) else: print newname, 'already exists!' 

ls has some switches (like --quote-name, --escape, --literal) for dealing with unprintable characters, but in this case it seems the character is "printable" but not "typeable" (at least on my keyboard!), so none of these switches seem to help.

Therefore, as a general "brute force" approach to get rid of files with any characters in their names, you can do this:

$ /bin/ls -1A|cat -n # list all files (except . and ..), 1 per line, add line numbers 1 ♫ 2 f1.txt 3 f2.txt 

Find the line containing the offending file. Quite likely it will be the 1st line, but let's say it's the 5th. Print line 5 and hex encode it:

$ /bin/ls -1A|sed -n 5p|xxd -g 1 0000000: e2 99 ab 0a .... 

Ignoring the 0a (newline) character, construct an escape string, and use the -e option of echo to translate the escapes:

$ echo -e '\xe2\x99\xab' ♫ 

Now you can copy/move/delete it like this:

$ cp -vi $(echo -e '\xe2\x99\xab') better_name ‘♫’ -> ‘better_name’ 

Also, if you're not confined to using shell script, you could do it in Python like this:

$ python >>> import os >>> os.listdir('.') [ ..., '\xe2\x99\xab', ... ] >>> print '\xe2\x99\xab' ♫ >>> os.rename('\xe2\x99\xab', 'better_name') 

ls has some switches (like --quote-name, --escape, --literal) for dealing with unprintable characters, but in this case it seems the character is "printable" but not "typeable" (at least on my keyboard!), so none of these switches seem to help.

Therefore, as a general "brute force" approach to get rid of files with any characters in their names, you can do this:

$ /bin/ls -1A|cat -n # list all files (except . and ..), 1 per line, add line numbers 1 ♫ 2 f1.txt 3 f2.txt 

Find the line containing the offending file. Quite likely it will be the 1st line, but let's say it's the 5th. Print line 5 and hex encode it:

$ /bin/ls -1A|sed -n 5p|xxd -g 1 0000000: e2 99 ab 0a .... 

Ignoring the 0a (newline) character, construct an escape string, and use the -e option of echo to translate the escapes:

$ echo -e '\xe2\x99\xab' ♫ 

Now you can copy/move/delete it like this:

$ cp -vi $(echo -e '\xe2\x99\xab') better_name ‘♫’ -> ‘better_name’ 

Also, if you're not confined to using shell script, you could do it in Python like this:

$ python >>> import os >>> os.listdir('.') [ ..., '\xe2\x99\xab', ... ] >>> print '\xe2\x99\xab' ♫ >>> import shutil >>> shutil.copy('\xe2\x99\xab', 'better_name') 

Using this approach, you can process many files, you just have to write the logic for selecting the correct files, and renaming them without clobbering, etc:

for f in os.listdir('.'): if not f.isalnum(): newname = generate_newname(f) if not os.path.exists(newname): shutil.copy(f, newname) else: print newname, 'already exists!' 
question was about copying, not removing
Source Link

ls has some switches (like --quote-name, --escape, --literal) for dealing with unprintable characters, but in this case it seems the character is "printable" but not "typeable" (at least on my keyboard!), so none of these switches seem to help.

Therefore, as a general "brute force" approach to get rid of files with any characters in their names, you can do this:

$ /bin/ls -1A|cat -n # list all files (except . and ..), 1 per line, add line numbers 1 ♫ 2 f1.txt 3 f2.txt 

Find the line containing the offending file. Quite likely it will be the 1st line, but let's say it's the 5th. Print line 5 and hex encode it:

$ /bin/ls -1A|sed -n 5p|xxd -g 1 0000000: e2 99 ab 0a .... 

Ignoring the 0a (newline) character, construct an escape string, and use the -e option of echo to translate the escapes:

$ echo -e '\xe2\x99\xab' ♫ 

Now you can removecopy/move/delete it like this:

$ rmcp -vi $(echo -e '\xe2\x99\xab') rm: remove regular file better_name ‘♫’? y removed-> ‘♫’‘better_name’ 

Also, if you're not confined to using shell script, you could do it in Python like this:

$ python >>> import os >>> os.listdir('.') [ ..., '\xe2\x99\xab', ... ] >>> print '\xe2\x99\xab' ♫ >>> os.unlinkrename('\xe2\x99\xab', 'better_name') 

ls has some switches (like --quote-name, --escape, --literal) for dealing with unprintable characters, but in this case it seems the character is "printable" but not "typeable" (at least on my keyboard!), so none of these switches seem to help.

Therefore, as a general "brute force" approach to get rid of files with any characters in their names, you can do this:

$ /bin/ls -1A|cat -n # list all files (except . and ..), 1 per line, add line numbers 1 ♫ 2 f1.txt 3 f2.txt 

Find the line containing the offending file. Quite likely it will be the 1st line, but let's say it's the 5th. Print line 5 and hex encode it:

$ /bin/ls -1A|sed -n 5p|xxd -g 1 0000000: e2 99 ab 0a .... 

Ignoring the 0a (newline) character, construct an escape string, and use the -e option of echo to translate the escapes:

$ echo -e '\xe2\x99\xab' ♫ 

Now you can remove it like this:

$ rm -vi $(echo -e '\xe2\x99\xab') rm: remove regular file ‘♫’? y removed ‘♫’ 

Also, if you're not confined to using shell script, you could do it in Python like this:

$ python >>> import os >>> os.listdir('.') [ ..., '\xe2\x99\xab', ... ] >>> print '\xe2\x99\xab' ♫ >>> os.unlink('\xe2\x99\xab') 

ls has some switches (like --quote-name, --escape, --literal) for dealing with unprintable characters, but in this case it seems the character is "printable" but not "typeable" (at least on my keyboard!), so none of these switches seem to help.

Therefore, as a general "brute force" approach to get rid of files with any characters in their names, you can do this:

$ /bin/ls -1A|cat -n # list all files (except . and ..), 1 per line, add line numbers 1 ♫ 2 f1.txt 3 f2.txt 

Find the line containing the offending file. Quite likely it will be the 1st line, but let's say it's the 5th. Print line 5 and hex encode it:

$ /bin/ls -1A|sed -n 5p|xxd -g 1 0000000: e2 99 ab 0a .... 

Ignoring the 0a (newline) character, construct an escape string, and use the -e option of echo to translate the escapes:

$ echo -e '\xe2\x99\xab' ♫ 

Now you can copy/move/delete it like this:

$ cp -vi $(echo -e '\xe2\x99\xab') better_name ‘♫’ -> ‘better_name’ 

Also, if you're not confined to using shell script, you could do it in Python like this:

$ python >>> import os >>> os.listdir('.') [ ..., '\xe2\x99\xab', ... ] >>> print '\xe2\x99\xab' ♫ >>> os.rename('\xe2\x99\xab', 'better_name') 
Source Link

ls has some switches (like --quote-name, --escape, --literal) for dealing with unprintable characters, but in this case it seems the character is "printable" but not "typeable" (at least on my keyboard!), so none of these switches seem to help.

Therefore, as a general "brute force" approach to get rid of files with any characters in their names, you can do this:

$ /bin/ls -1A|cat -n # list all files (except . and ..), 1 per line, add line numbers 1 ♫ 2 f1.txt 3 f2.txt 

Find the line containing the offending file. Quite likely it will be the 1st line, but let's say it's the 5th. Print line 5 and hex encode it:

$ /bin/ls -1A|sed -n 5p|xxd -g 1 0000000: e2 99 ab 0a .... 

Ignoring the 0a (newline) character, construct an escape string, and use the -e option of echo to translate the escapes:

$ echo -e '\xe2\x99\xab' ♫ 

Now you can remove it like this:

$ rm -vi $(echo -e '\xe2\x99\xab') rm: remove regular file ‘♫’? y removed ‘♫’ 

Also, if you're not confined to using shell script, you could do it in Python like this:

$ python >>> import os >>> os.listdir('.') [ ..., '\xe2\x99\xab', ... ] >>> print '\xe2\x99\xab' ♫ >>> os.unlink('\xe2\x99\xab')