Struggling with this one and Googling it doesn't seem to be giving me solution that works.
I have a folder named…
file å?? name.txt
for example and to avoid problems, I want to rename it however I'm struggling to work out how. I've tried using ' '
and I also tried using \
before each special character e.g. 'file \å\?\? name \(2008\).txt'
but I just get the following error…
-bash: cd: file \å\?\? name \(2008\).txt : No such file or directory
Is this improper use of \
or do I need an alternative approach?
Thanks
Best Answer
The non-ASCII characters are not the problem, your shell can deal with
å
perfectly well. The issue is that your file is not actually namedå??
. If it were,rm 'å??'
or evenrm å??
would have worked.You assume it's
å??
because that's whatls
shows, and that's a reasonable assumption, butls
will show various things as?
. For example:As you can see above, newlines, tabs, carriage returns, bells and vertical tabs (among others) are all shown as
?
. Only the first file/directory of the ones created above actually has?
in its name. We can confirm this withls -b
:So, you can either run
ls -b
to get the right file name and then use ANSI C quoting to rename it:Alternatively, you can use a glob to match all files/directories whose name starts with
file å
(note: this will only work if you just have one) :Or, rename all files/directories whose name contains non alphanumeric characters (again, only useful for cases where you have a single such case):
The strange
!(*([[:graph:]]))
needs some explaining.extglob
enables extended globbing which lets us use!(foo)
to match "not foo". The[[:graph:]]
character class matches all printable characters (not tabs, newlines etc.) Therefore, the negated match!(*([[:graph:]]))
will match all file/dirnames with non-printing characters.If you need to deal with more than one such case, use a loop. Something like:
The
${dir//[^[:graph:]]/_}
is the directory name with all non-printing characters replaced by_
. The problem with this approach is that you can have different source directories which will end up with the same name (e.g.foo\n
andfoo\t
will both becomefoo_
). If that is a problem, just rename using a counter as well:That would result in: