如何删除这些名称的文件?

时间:2014-03-09 17:31:24

标签: linux shell

我的主文件夹中有两个名为“'?”的文件。和“'?;?” (没有双引号)。我该如何删除它们?我试图使用转义,但它不起作用。

3 个答案:

答案 0 :(得分:4)

使用单引号或双引号来避免通配符扩展。 ?是一个通配符,表示shell与任何一个单个字符匹配。通过将其放在引号中,您告诉shell不要执行通配符扩展。

rm '?' '?;?'
rm "?" "?;?"

这将删除名为“?”的两个文件和“?;?”

你也可以使用反斜杠来引用对shell有特殊意义的单个字符,这样你就可以这样做

rm \? \?\;\?

注意你必须引用'?'防止路径名扩展,你必须引用';'因此shell不会将其解释为分离命令。

如果省略引号,那么shell会以不同方式解析它。这是我跑过的一个实验。

$ for i in {1..4}; do for j in {a..c}; do touch "$i;$j" $j '?' '?;?';done;done
$ ls
1;a  1;b  1;c  2;a  2;b  2;c  3;a  3;b  3;c  4;a  4;b  4;c  ?  ?;?  a  b  c
$ rm ? ?;?
rm: cannot remove `?': No such file or directory
rm: cannot remove `a': No such file or directory
rm: cannot remove `b': No such file or directory
rm: cannot remove `c': No such file or directory
bash: ?: command not found
$ rm `echo "?" "?;?"`
rm: cannot remove `?': No such file or directory
$ 

这里发生的事情是shell做了路径名扩展,所以

rm ? ?;?

成了

rm ? a b c ? a b c;? a b c

rm命令删除了文件a b c?然后抱怨找不到以下文件(它们已被删除)。分号分隔命令,然后尝试调用'?'命令传递参数“a”“b”“c”......但是没有'?' command - 名为'?'的文件刚刚被删除,无论如何它都不可执行 - 所以shell抱怨“?”找不到命令。

如果要删除所有匹配“?”的文件和“?;?”你需要欺骗shell扩展那些,我喜欢这样做

rm `echo "?" "?;?"`

这是由shell分两步扩展的,首先它运行echo "?" "?;?",这导致两个字符串,“?”和“?;?”,然后它使用这些字符串进行路径名扩展,以生成rm的参数,从而产生

rm  ? 1;a  1;b  1;c  2;a  2;b  2;c  3;a  3;b  3;c  4;a  4;b  4;c ?;?

请注意'?'的通配符扩展这次没有产生任何匹配的文件(它们之前已被删除),所以shell传递'?'作为rm的参数,成功删除作为参数传递的所有文件,除了'?'所以它抱怨这个。

这是另一个实验

$ for i in {1..4}; do for j in {a..c}; do touch "$i;$j" $j '?' '?;?';done;done
$ ls
1;a  1;b  1;c  2;a  2;b  2;c  3;a  3;b  3;c  4;a  4;b  4;c  ?  ?;?  a  b  c
$ rm "?" "?;?"
$ ls
1;a  1;b  1;c  2;a  2;b  2;c  3;a  3;b  3;c  4;a  4;b  4;c  a  b  c
$ rm `echo "?" "?;?"`
$ ls
$ 

有关更多信息,请参阅globbing的手册页

man 7 glob
  

通配符匹配          字符串是通配符模式,如果它包含字符'?','*'或'[')之一。 Globbing就是这样的操作          将通配符模式扩展到与模式匹配的路径名列表中。匹配定义如下:

   A '?' (not between brackets) matches any single character.

   A '*' (not between brackets) matches any string, including the empty string.

答案 1 :(得分:2)

请注意,ls可以为任意不可打印的字符报告问号,因此您作为文件名获得的内容可能不包含问号。

您可以使用ls -b命令或ls | cat来发现此信息。

作为一个复杂的例子,完成补救措施,我创建了一个像这样的脚本convolvulus

set -x
mkdir convoluted &&
(
cd convoluted
cp /dev/null "$(ls -la | sed 1d)"
ls
ls -b
ls | cat
ls -la | cat
cp /dev/null $'\n'
cp /dev/null $'\n;\n'
ls -als | cat
ls -lab
ls
ls | cat
rm $'\n' $'\n;\n' d*
ls -a
)
rm -fr convoluted

跑步时,它产生了:

$ bash convolvulus 2>&1 | so
+ mkdir convoluted
+ cd convoluted
++ ls -la
++ sed 1d
+ cp /dev/null 'drwxr-xr-x    2 jleffler  staff    68 Mar  9 11:58 .
drwxr-xr-x  240 jleffler  staff  8160 Mar  9 11:58 ..'
+ ls
drwxr-xr-x    2 jleffler  staff    68 Mar  9 11:58 .
drwxr-xr-x  240 jleffler  staff  8160 Mar  9 11:58 ..
+ ls -b
drwxr-xr-x    2 jleffler  staff    68 Mar  9 11:58 .\ndrwxr-xr-x  240 jleffler  staff  8160 Mar  9 11:58 ..
+ ls
+ cat
drwxr-xr-x    2 jleffler  staff    68 Mar  9 11:58 .
drwxr-xr-x  240 jleffler  staff  8160 Mar  9 11:58 ..
+ ls -la
+ cat
total 0
drwxr-xr-x    3 jleffler  staff   102 Mar  9 11:58 .
drwxr-xr-x  240 jleffler  staff  8160 Mar  9 11:58 ..
-rw-r--r--    1 jleffler  staff     0 Mar  9 11:58 drwxr-xr-x    2 jleffler  staff    68 Mar  9 11:58 .
drwxr-xr-x  240 jleffler  staff  8160 Mar  9 11:58 ..
+ cp /dev/null '
'
+ cp /dev/null '
;
'
+ ls -als
+ cat
total 0
0 -rw-r--r--    1 jleffler  staff     0 Mar  9 11:58 

0 -rw-r--r--    1 jleffler  staff     0 Mar  9 11:58 
;

0 drwxr-xr-x    5 jleffler  staff   170 Mar  9 11:58 .
0 drwxr-xr-x  240 jleffler  staff  8160 Mar  9 11:58 ..
0 -rw-r--r--    1 jleffler  staff     0 Mar  9 11:58 drwxr-xr-x    2 jleffler  staff    68 Mar  9 11:58 .
drwxr-xr-x  240 jleffler  staff  8160 Mar  9 11:58 ..
+ ls -lab
total 0
-rw-r--r--    1 jleffler  staff     0 Mar  9 11:58 \n
-rw-r--r--    1 jleffler  staff     0 Mar  9 11:58 \n;\n
drwxr-xr-x    5 jleffler  staff   170 Mar  9 11:58 .
drwxr-xr-x  240 jleffler  staff  8160 Mar  9 11:58 ..
-rw-r--r--    1 jleffler  staff     0 Mar  9 11:58 drwxr-xr-x    2 jleffler  staff    68 Mar  9 11:58 .\ndrwxr-xr-x  240 jleffler  staff  8160 Mar  9 11:58 ..
+ ls



;

drwxr-xr-x    2 jleffler  staff    68 Mar  9 11:58 .
drwxr-xr-x  240 jleffler  staff  8160 Mar  9 11:58 ..
+ ls
+ cat



;

drwxr-xr-x    2 jleffler  staff    68 Mar  9 11:58 .
drwxr-xr-x  240 jleffler  staff  8160 Mar  9 11:58 ..
+ rm '
' '
;
' 'drwxr-xr-x    2 jleffler  staff    68 Mar  9 11:58 .
drwxr-xr-x  240 jleffler  staff  8160 Mar  9 11:58 ..'
+ ls -a
.
..
+ rm -fr convoluted
$

玩得开心!

-b的{​​{1}}选项适用于GNU ls以及适用于Mac OS X和BSD ls(但未由POSIX定义)。 ls表示法是Bash ANSI-C Quoting

答案 2 :(得分:1)

在文件名周围使用引号:

$ ls
?  ?;?
$ rm '?'
$ ls
?;?
$ rm "?;?"
$ ls
$