Bash shell脚本中文件名中的空格

Bash shell脚本中文件名中的空格,bash,shell,Bash,Shell,我有一个处理一些文件的shell脚本。问题是文件名中可能有空格,我做到了: #!/bin/sh FILE=`echo $FILE | sed -e 's/[[:space:]]/\\ /g'` cat $FILE 因此变量FILE是从其他程序传入的文件名。它可能包含空格。我使用sed用\来避开空白,以便命令行实用程序能够处理它 问题是它不起作用echo$FILE | sed-e的/[:space:][]/\\\/g'本身按预期工作,但当分配给文件时,转义字符\再次消失。因此,cat将其解释为多

我有一个处理一些文件的shell脚本。问题是文件名中可能有空格,我做到了:

#!/bin/sh
FILE=`echo $FILE | sed -e 's/[[:space:]]/\\ /g'`
cat $FILE
因此变量
FILE
是从其他程序传入的文件名。它可能包含空格。我使用
sed
\
来避开空白,以便命令行实用程序能够处理它


问题是它不起作用
echo$FILE | sed-e的/[:space:][]/\\\/g'
本身按预期工作,但当分配给
文件时,转义字符
\
再次消失。因此,
cat
将其解释为多个参数。我想知道它为什么会这样?有什么办法可以避免吗?如果有多个空格,比如说
一些糟糕的file.txt
,应该用
some\\\糟糕的\\file.txt
替换。谢谢。

不要试图将转义字符放在数据中——它们只作为语法使用(也就是说,反斜杠在源代码中有意义,而不是在数据中)

也就是说,以下各项完全符合给定条件:

file='some   terrible  file.txt'
cat "$file"
…同样,如果名称来自glob结果或类似结果:

# this operates in a temporary directory to not change the filesystem you're running it in
tempdir=$(mktemp -d "${TMPDIR:-/tmp}/testdir.XXXXXX") && (
  cd "$tempdir" || exit
  echo 'example' >'some  terrible  file.txt'
  for file in *.txt; do
    printf 'Found file %q with the following contents:\n' "$file"
    cat "$file"
  done
  rm -rf "$tempdir"
)

不要试图将转义字符放在数据中——它们只作为语法使用(也就是说,反斜杠在源代码中有意义,而不是在数据中)

也就是说,以下各项完全符合给定条件:

file='some   terrible  file.txt'
cat "$file"
…同样,如果名称来自glob结果或类似结果:

# this operates in a temporary directory to not change the filesystem you're running it in
tempdir=$(mktemp -d "${TMPDIR:-/tmp}/testdir.XXXXXX") && (
  cd "$tempdir" || exit
  echo 'example' >'some  terrible  file.txt'
  for file in *.txt; do
    printf 'Found file %q with the following contents:\n' "$file"
    cat "$file"
  done
  rm -rf "$tempdir"
)

别把事情弄得太复杂了

cat "$FILE"
这就是你所需要的。注意变量周围的引号。它们防止变量在空白处展开和拆分。您应该总是这样编写shell程序。始终在所有变量周围加引号,除非您确实希望shell展开它们

for i in $pattern; do

那没关系。

不要把事情弄得更复杂

cat "$FILE"
这就是你所需要的。注意变量周围的引号。它们防止变量在空白处展开和拆分。您应该总是这样编写shell程序。始终在所有变量周围加引号,除非您确实希望shell展开它们

for i in $pattern; do

没关系。

多用引号。变量中的转义字符是完全无用的——转义和引号是代码语法;如果变量内容中嵌入的语法在扩展时得到尊重,那么用shell派生语言编写安全代码实际上是不可能的,因为这样的数据可以避免引用,执行自己的扩展,否则就会产生目前只有使用
eval
才可能发生的所有问题。如果您的shebang是
,请参见BTW的BashFAQ#50/bin/sh
,这不是bash脚本,而是POSIX sh脚本。如果它以
#开头,那么它只是一个bash脚本/bin/bash
。此外,不要对自己的变量使用所有大写名称。请参阅相关的标准文档--在环境变量中,所有大写变量都由shell和系统使用,小写名称保留供用户使用。Shell变量与环境变量共享名称空间,因此此约定也适用于它们,以避免意外地覆盖对系统有意义的变量。请使用更多引号。变量中的转义字符是完全无用的——转义和引号是代码语法;如果变量内容中嵌入的语法在扩展时得到尊重,那么用shell派生语言编写安全代码实际上是不可能的,因为这样的数据可以避免引用,执行自己的扩展,否则就会产生目前只有使用
eval
才可能发生的所有问题。如果您的shebang是
,请参见BTW的BashFAQ#50/bin/sh
,这不是bash脚本,而是POSIX sh脚本。如果它以
#开头,那么它只是一个bash脚本/bin/bash
。此外,不要对自己的变量使用所有大写名称。请参阅相关的标准文档--在环境变量中,所有大写变量都由shell和系统使用,小写名称保留供用户使用。Shell变量与环境变量共享名称空间,因此此约定也适用于它们,以避免意外地覆盖对系统有意义的变量。
for i in$pattern;do
也很不幸——您不能用那种方式表示像
“hello world”*.txt这样的模式。最好扩展到一个数组中并迭代数组的内容。
for i in$pattern;do
也很不幸——您不能用那种方式表示像
“hello world”*.txt这样的模式。最好扩展到一个数组并迭代数组的内容。