Linux 下如何处理包含空格和特殊字符的文件名

我们经常会看到文件名和文件夹名。大多数时候文件/文件夹的名字和内容相关并以数字和字母开头。字母加数字的文件名最常见,应用也很广泛,但总会需要处理一些包含特殊字符的文件名/文件夹名。

注意:我们可能有各种类型的文件,但是为了简单以及方便实现,在本文中我们只用文本文件(.txt)做演示。

最常见的文件名例子:


  1. abc.txt
  2. avi.txt
  3. debian.txt
  4. ...

数字文件名例子:


  1. 121.txt
  2. 3221.txt
  3. 674659.txt
  4. ...

字母数字文件名例子:


  1. eg84235.txt
  2. 3kf43nl2.txt
  3. 2323ddw.txt
  4. ...

包含特殊字符的文件名的例子,并不常见:


  1. #232.txt
  2. #bkf.txt
  3. #bjsd3469.txt
  4. #121nkfd.txt
  5. -2232.txt
  6. -fbjdew.txt
  7. -gi32kj.txt
  8. --321.txt
  9. --bk34.txt
  10. ...

一个显而易见的问题是 - 在这个星球上有谁会创建和处理包含井号(#),分号(;),破折号(-)或其他特殊字符的文件/文件夹啊。

我和你想的一样,这种文件名确实不常见,不过在你必须得处理这种文件名的时候你的 shell 也不应该出错或罢工。而且技术上来说,Linux 下的一切比如文件夹、驱动器或其他所有的都被当作文件处理。

处理名字包含破折号(-)的文件

创建以破折号(-)开头的文件,比如 -abx.txt。


  1. $ touch -abc.txt

测试输出


  1. touch: invalid option -- 'b'
  2. Try 'touch --help' for more information.

出现上面错误的原因是,shell 把破折号(-)之后的内容认作参数了,而很明显没有这样的参数,所以报错。

要解决这个问题,我们得告诉 Bash shell(是的,这里以及本文后面的大多数例子都是基于 BASH 环境)不要将特殊字符(这里是破折号)后的字符解释为参数。

有两种方法解决这个错误:


  1. $ touch -- -abc.txt [方法 #1]
  2. $ touch ./-abc.txt [方法 #2]

你可以通过运行命令 ls 或 ls -l 列出详细信息来检查通过上面两种方式创建的文件。


  1. $ ls -l
  2. total 0
  3. -rw-r--r-- 1 avi avi 0 Jun 8 11:05 -abc.txt

要编辑上述文件可以这样:


  1. $ nano -- -abc.txt
  2. 或者
  3. $ nano ./-abc.txt

注意:你可以将 nano 替换为任何其他你喜欢的编辑器比如说 vim:


  1. $ vim -- -abc.txt
  2. 或者
  3. $ vim ./-abc.txt

如果只是简单地移动文件可以这样:


  1. $ mv -- -abc.txt -a.txt
  2. 或者
  3. $ mv -- -a.txt -abc.txt

删除这种文件,可以这样:


  1. $ rm -- -abc.txt
  2. 或者
  3. $ rm ./-abc.txt

如果一个目录下有大量这种名字包含破折号的文件,要一次全部删除的话,可以这样:


  1. $ rm ./-*

重要:

  1. 上面讨论的规则可以同样应用于名字中包含任意数量以及任意位置的连接符号的文件。就是说,-a-b-c.txt,ab-c.txt,abc-.txt,等等。
  2. 上面讨论的规则可以同样应用于名字中包含任意数量以及任意位置连接符号的文件夹,除了一种情况,在删除一个文件夹的时候你得这样使用rm -rf

    $ rm -rf -- -abc 或者 $ rm -rf ./-abc

处理名字包含井号(#)的文件

符号#在 BASH 里有非常特别的含义。#之后的一切都会被认为是评论,因此会被 BASH 忽略。

通过例子来加深理解:

创建一个名字是 #abc.txt 的文件:


  1. $ touch #abc.txt

测试输出


  1. touch: missing file operand
  2. Try 'touch --help' for more information.

出现上面错误的原因是,BASH 将 #abc.txt 解释为评论而忽略了。所以命令 touch没有收到任何文件作为参数,所以导致这个错误。

要解决这个问题,你可能需要告诉 BASH 不要将 # 解释为评论。


  1. $ touch ./#abc.txt
  2. 或者
  3. $ touch '#abc.txt'

检查刚创建的文件:


  1. $ ls -l
  2. total 0
  3. -rw-r--r-- 1 avi avi 0 Jun 8 12:14 #abc.txt

现在创建名字中除了开头的其他地方包含 # 的文件。


  1. $ touch ./a#bc.txt
  2. $ touch ./abc#.txt
  3. 或者
  4. $ touch 'a#bc.txt'
  5. $ touch 'abc#.txt'

运行 ‘ls -l‘ 来检查:


  1. $ ls -l
  2. total 0
  3. -rw-r--r-- 1 avi avi 0 Jun 8 12:16 a#bc.txt
  4. -rw-r--r-- 1 avi avi 0 Jun 8 12:16 abc#.txt

如果同时创建两个文件(比如 a 和 #bc)会怎么样:


  1. $ touch a.txt #bc.txt

检查刚创建的文件:


  1. $ ls -l
  2. total 0
  3. -rw-r--r-- 1 avi avi 0 Jun 8 12:18 a.txt

很明显上面的例子中只创建了文件 a 而文件 #bc 被忽略了。对于上面的情况我们可以这样做,


  1. $ touch a.txt ./#bc.txt
  2. 或者
  3. $ touch a.txt '#bc.txt'

检查一下:


  1. $ ls -l
  2. total 0
  3. -rw-r--r-- 1 avi avi 0 Jun 8 12:20 a.txt
  4. -rw-r--r-- 1 avi avi 0 Jun 8 12:20 #bc.txt

可以这样移动文件:


  1. $ mv ./#bc.txt ./#cd.txt
  2. 或者
  3. $ mv '#bc.txt' '#cd.txt'

这样拷贝:


  1. $ cp ./#cd.txt ./#de.txt
  2. 或者
  3. $ cp '#cd.txt' '#de.txt'

可以使用你喜欢的编辑器来编辑文件:


  1. $ vi ./#cd.txt
  2. 或者
  3. $ vi '#cd.txt'
  4. $ nano ./#cd.txt
  5. 或者
  6. $ nano '#cd.txt'

这样删除:


  1. $ rm ./#bc.txt
  2. 或者
  3. $ rm '#bc.txt'

要删除所有以井号(#)开头的文件,可以这样:


  1. # rm ./#*

处理名字包含分号(;)的文件

如果你还不知道的话,分号在 BASH 里起到命令分隔的作用,其他 shell 可能也是一样的。分号作为分隔符可以让你一次执行几个命令。你碰到过名字包含分号的文件吗?如果没有的话,这里有例子。

创建一个名字包含分号的文件。


  1. $ touch ;abc.txt

测试输出


  1. touch: missing file operand
  2. Try 'touch --help' for more information.
  3. bash: abc.txt: command not found

出现上面错误的原因是,在运行上面命令的时候 BASH 会把 touch 解释为一个命令但是在分号前没有任何文件参数,所以报告错误。然后报告的另一个错误找不到命令 abc.txt,只是因为在分号后 BASH 会期望另一个新的命令,而 abc.txt 并不是一个命令。

要解决这个问题,我们得告诉 BASH 不要将分号解释为命令分隔符,例如:


  1. $ touch ./';abc.txt'
  2. 或者
  3. $ touch ';abc.txt'

注意:我们将文件名用单引号 '' 包含起来。这样可以告诉 BASH 分号 ; 是文件名的一部分而不是命令分隔符。

对名字包含分号的文件和文件夹的其他操作(就是,拷贝、移动、删除)可以直接将名字用单引号包含起来就好了。

处理名字包含其他特殊字符的文件/文件夹

文件名包含加号 (+)

不需要任何特殊处理,按平时的方式做就好了,比如下面测试的文件名。


  1. $ touch +12.txt

文件名包含美元符 ($)

你需要将文件名用单引号括起来,像处理分号那样的方式。然后就很简单了。


  1. $ touch '$12.txt'

文件名包含百分号 (%)

不需要任何特殊处理,当作一个普通文件就可以了。


  1. $ touch %12.txt

文件名包含星号 (*)

需要用单引号括起来或使用反斜杠转义。(LCTT 译注:此处原文有误,已修改。)


  1. $ touch *12.txt

注意:当你需要删除星号开头的文件时,千万不要用类似下面的命令。


  1. $ rm *
  2. 或者
  3. $ rm -rf *

而是用这样的命令,(LCTT 译注:此处原文有误,已修改)


  1. $ rm ./'*.txt'

文件名包含叹号 (!)

只要将文件名用单引号括起来,其他的就一样了。


  1. $ touch '!12.txt'

文件名包含小老鼠 (@)

没有什么特别的,可以将名字包含小老鼠的文件当作普通文件。


  1. $ touch '@12.txt'

文件名包含 ^

不需要特殊处理。可以将名字包含 ^ 的文件当作普通文件。


  1. $ touch ^12.txt

文件名包含 (&)

将文件名用单引号括起来,然后就可以操作了。


  1. $ touch '&12.txt'

文件名包含括号 ()

如果文件名包含括号,你需要将文件名用单引号括起来。


  1. $ touch '(12.txt)'

文件名包含花括号 {}

用单引号括起来或使用反斜杠转义。(LCTT 译注:此处原文有误,已修改)


  1. $ touch '{12.txt}'

文件名包含尖括号 <>

名字包含尖括号的文件需要用单引号括起来。


  1. $ touch '<12.txt>'

文件名包含方括号 [ ]

用单引号括起来或使用反斜杠转义。(LCTT 译注:此处原文有误,已修改)


  1. $ touch '[12.txt]'

文件名包含下划线 (_)

这个非常普遍,不需要特殊对待。当作普通文件随意处理。


  1. $ touch _12.txt

文件名包含等号 (=)

用单引号括起来或使用反斜杠转义。(LCTT 译注:此处原文有误,已修改)


  1. $ touch '=12.txt'

处理反斜杠 ()

反斜杠会告诉 shell 忽略后面字符的特殊含义。你必须将文件名用单引号括起来,就像处理分号那样。其他的就没什么了。


  1. $ touch '\12.txt'

包含斜杠的特殊情形

除非你的文件系统有问题,否则你不能创建名字包含斜杠的文件。没办法转义斜杠。

所以如果你能创建类似 ‘/12.txt’ 或者 ‘b/c.txt’ 这样的文件,那要么你的文件系统有问题,或者支持 Unicode,这样你可以创建包含斜杠的文件。只是这样并不是真的斜杠,而是一个看起来像斜杠的 Unicode 字符。

文件名包含问号 (?)

用单引号括起来或使用反斜杠转义。(LCTT 译注:此处原文有误,已修改)


  1. $ touch '?12.txt'

文件名包含点 (.)

在 Linux 里以点 (.) 开头的文件非常特别,被称为点文件。它们通常是隐藏的配置文件或系统文件。你需要使用 ls 命令的 ‘-a‘ 或 ‘-A‘ 开关来查看这种文件。

创建,编辑,重命名和删除这种文件很直接。


  1. $ touch .12.txt

注意:在 Linux 里你可能碰到名字包含许多点 (.) 的文件。不像其他操作系统,文件名里的点并不意味着分隔名字和扩展后缀。你可以创建名字包含多个点的文件:


  1. $ touch 1.2.3.4.5.6.7.8.9.10.txt

检查一下:


  1. $ ls -l
  2. total 0
  3. -rw-r--r-- 1 avi avi 0 Jun 8 14:32 1.2.3.4.5.6.7.8.9.10.txt

文件名包含逗号 (,)

你可以在文件名中使用逗号,可以有任意多个而不用特殊对待。就像平时普通名字文件那样处理。


  1. $ touch ,12.txt
  2. 或者
  3. $ touch ,12,.txt

文件名包含冒号 (:)

用单引号括起来或使用反斜杠转义。(LCTT 译注:此处原文有误,已修改)


  1. $ touch ':12.txt'
  2. 或者
  3. $ touch ':12:.txt'

文件名包含引号(单引号和双引号)

要在文件名里使用引号,我们需要使用交替规则。例如,如果你需要在文件名里使用单引号,那就用双引号把文件名括起来。而如果你需要在文件名里使用双引号,那就用单引号把文件名括起来。(LCTT 译注:或者如果单引号和双引号混杂的情况,你也可以用反斜杠转义。)


  1. $ touch "15'.txt"
  2. 以及
  3. $ touch '15".txt'

文件名包含波浪号 (~)

Linux 下一些像 emacs 这样的文本编辑器在编辑文件的时候会创建备份文件。这个备份文件的名字是在原文件名后面附加一个波浪号。你可以在文件名任意位置使用波浪号,例如:


  1. $ touch ~1a.txt
  2. 或者
  3. $touch 2b~.txt

文件名包含空格

创建名字的字符/单词之间包含空格的文件,比如 “hi my name is avishek.txt”。

最好不要在文件名里使用空格,如果你必须要分隔可读的名字,可以使用下划线或横杠。不过,你还是需要创建这样的文件的话,你可以用反斜杠来转义下一个字符。要创建上面名字的文件可以这样做。


  1. $ touch hi\ my\ name\ is\ avishek.txt
  2. hi my name is avishek.txt

我已经尝试覆盖你可能碰到的所有情况。上面大多数测试都在 BASH Shell 里完成,可能在其他 shell 下会有差异。

如果你觉得我遗漏了什么(这很正常也符合人性),请把你的建议发表到下面的评论里。保持联系,多评论。不要走开!求点赞求分享求扩散!


原文发布时间为:2015-07-08


本文来自合作伙伴“Linux中国”

时间: 2024-10-31 18:18:50

Linux 下如何处理包含空格和特殊字符的文件名的相关文章

linux下查找包含utf8 BOM头的文件,并删除BOM头信息(FEEF)

UTF-8 编码的文件可以分为no BOM 和 BOM两种格式. 有bom头的存储或者字节流,它一定是unicode字符集编码.到底属于那一种(utf-8还是utf-16或是utf-32),通过头可以判断出来. 在utf-8编码文件中BOM在文件头部,占用三个字节,用来标示该文件属于utf-8编码 UTF-8的BOM是 EFBBBF,因为UE载入UTF-8文件会转成Utf16,上述的EFBBBF 在Utf16中是FFFE(Unicode-LE的BOM) 1.editplus去BOM头的方法  编

linux下查看文件-Linux下如果要在根目录查找内容包含某个字符串的文件,怎么查找啊,谢谢

问题描述 Linux下如果要在根目录查找内容包含某个字符串的文件,怎么查找啊,谢谢 我想在Linux下查看某个函数的定义在那个文件里,前提是我不知道在那个文件夹下面,有谁可以帮我看看啊,谢谢 解决方案 在某个目录下的所有文件的内容中,查找包含某个字符串的文件Linux下查找包含字符串的文件命令linux下查找某个目录下包含某个字符串的文件 解决方案二: 问题终于解决了,非常感谢! 解决方案三: grep -rHwns "search str" / 解决方案四: grep -n &quo

linux下查找某个目录下包含某个字符串的文件

有时候要找以前写的一段程序,但是日久健忘,只记得程序片段里包含某个文字. 那么如何在linux下寻找包含某段文字的文件呢? 强大的find命令可以帮你完成不可能的任务. 比如我只记得我的程序里包含唯一的字符串"111cn.net",于是: 查找目录下的所有文件中是否含有某个字符串 find .|xargs grep -ri "111cn.net" 查找目录下的所有文件中是否含有某个字符串,并且只打印出文件名 find .|xargs grep -ri "1

Linux下批量修改文件名(rename)

原文地址: http://blog.csdn.net/sea_shore/article/details/6102437 1.rename命令批量修改文件名, 其实linux下可以使用别的办法来批量修改文件名, 不过rename实在太方便了 比如把所有的表为cdb1_* 修改为cdb_*的在本目录下只需要# rename 'cdb1' 'cdb' * 以前都是写个for循环来做...想想多傻啊, 呵呵 rename还有更多的功能, 建议man rename下 From:http://www.ha

linux下rm命令删除文件名中包含特殊字符的文件【转】

转自:http://blog.itpub.net/143526/viewspace-1060083/ 1. 删除带"-"的文件名的方法 2. 删除包含其它特殊字符的文件 3. 删除系统打不出的乱码文件名 [@more@] 1. 删除带"-"的文件名的方法 大部分是由于误操作的原因,产生了一些 特殊字符的文件 如 -foo rm --help用法:rm [选项]... 目录...Remove (unlink) the FILE(s). -d, --directory 

Linux如何查找处理文件名后包含空格的文件

Linux如何查找处理文件名后包含空格的文件   当Linux下文件名中出现空格这类特殊情况话,如何查找或确认那些文件名后有空格呢? 又怎么批量替换处理掉这些空格呢?     方法1: 输入文件名后使用Tab键,如果使用Tab键后面出现\ \ \这样的可见字符,那么该文件名包含空格.当然,这个方法弊端很大,例如,效率低下,不能批量查找,只有当你怀疑某个文件名后有空格,这个方法才比较凑效.另外,不能查找文件中间包含空格的文件名.如下测试所示:   [root@DB-Server kerry]# c

Linux下文本的高效处理

1 引言 所谓的文本处理是指对文本进行查找.替换.删除.排序等操作, linux在文本处理方面提供了大量优秀的工具, 使得在linux下进行文本处理极其的方便.  我们平常的工作中, 经常会用到文本处理, 比如日志分析, 比如文本抽取, 等等, 所以掌握好文本处理, 将会对我们的工作起到极大的作用.  下面我就来逐个介绍下这些强大的工具, 对于我觉得大家可能比较熟知的工具及用法, 我会略过, 或者粗讲下. 2 关于输入 Linux哲学中, 为了更好的组合各种命令达到更加强大的功能, 大多数文本处

Linux下时间范围判断的程序流程及其C代码实现

一.概述 在实际的软件开发项目中,经常会遇到需要判断时间范围的情况.例如,某软件要在某段时间内执行对过期数据的清理,在其它时间段不执行.为了体现程序的灵活性,一般都是在配置文件中设置时间段的始末值,这样可根据软件的实际安装环境进行配置.本文介绍判断当前时间是否在配置的时间范围内的程序流程,并给出了C代码实现.具体的需求描述如下: 在配置文件中按需配置某一开始时间和结束时间,编写程序判断当前系统时间是否在配置时间的范围之内.配置的时间格式为:HH:MM(小时:分),如08:30表示8点30分. 二

Linux下Tomcat与Apache Web服务器整合

apache|web|web服务|web服务器 1.引言      基于Web技术的Internet/Intranet近年来已经得到了广泛的应用,Intranet是以TCP/IP协议为基础.以Web为核心的企业内部网,用户通过低成本.简单易用的客户浏览器就能随时随地到企业的Web站点上查阅自己所需的数据.浏览器客户端操作界面的一致性避免了C/S模式客户端程序的多样性,而服务器端的开放和基于标准的连接方案使企业很方便地通过Internet同外界联系:同时,Web信息动态的.交互式的发布方式从根本上