为什么 `cat` 在这里列出文件而不是文件内容?
Why does `cat` list files instead of content of file here?
我今天尝试用 bash 脚本做一些棘手的事情,这让我质疑我对 bash 脚本的了解。
我有以下名为 get_ftypes.sh
的脚本,其中第一个输入参数是一个包含文件 globs:
的文件
for ftype in `cat `
do
echo "this is ftype $ftype"
done
例如,脚本会这样调用 get_ftypes.sh file_types
,file_types
会包含这样的内容:
*.txt
*.sh
我希望 echo
打印文件中的每一行,在本例中为 *.txt
、*.sh
等。但是,它扩展了 globbing, *
,它回显实际文件 names,而不是我期望的 globb。
这种行为有什么原因吗?我不知道为什么。谢谢。
在行 for ftype in `cat `
上,shell 执行 分词 和 路径扩展 。如果您不想那样,请使用 while
循环:
while read -r ftype
do
echo "this is ftype $ftype"
done <""
此循环一次从文件 </code> 中读取一行,并且在从每一行中删除前导和尾随空格的同时,不执行任何扩展。
(如果要保留前导和尾随空格,请使用 <code>while IFS= read -r ftype
)。
通常,当您遍历已经是 shell 定义的变量的项目时,for
循环很有用,例如 for x in "$@"
。如果您正在从外部命令或文件中读取内容,您通常需要一个 while read
循环。
替代方案不使用 shell
逐行处理文件时,通常可以使用 sed 或 awk 更有效地实现目标。作为使用 awk 的例子,上面的循环简化为:
$ awk '{print "this is ftype " [=11=]}' filetypes
this is ftype *.txt
this is ftype *.sh
echo $(cat foo)
将生成 foo
的内容,将它们拆分为单词,对每个单词进行 globs - 即,将 foo
的内容视为参数 - 然后将其插入当前命令行。
echo "$(cat foo)"
会将 foo
的内容作为单个参数生成,不将它们视为参数,不会 glob(但你只会通过循环一次)。
您想一次阅读 foo
一行;为此使用 while read -r ftype
。
我今天尝试用 bash 脚本做一些棘手的事情,这让我质疑我对 bash 脚本的了解。
我有以下名为 get_ftypes.sh
的脚本,其中第一个输入参数是一个包含文件 globs:
for ftype in `cat `
do
echo "this is ftype $ftype"
done
例如,脚本会这样调用 get_ftypes.sh file_types
,file_types
会包含这样的内容:
*.txt
*.sh
我希望 echo
打印文件中的每一行,在本例中为 *.txt
、*.sh
等。但是,它扩展了 globbing, *
,它回显实际文件 names,而不是我期望的 globb。
这种行为有什么原因吗?我不知道为什么。谢谢。
在行 for ftype in `cat `
上,shell 执行 分词 和 路径扩展 。如果您不想那样,请使用 while
循环:
while read -r ftype
do
echo "this is ftype $ftype"
done <""
此循环一次从文件 </code> 中读取一行,并且在从每一行中删除前导和尾随空格的同时,不执行任何扩展。
(如果要保留前导和尾随空格,请使用 <code>while IFS= read -r ftype
)。
通常,当您遍历已经是 shell 定义的变量的项目时,for
循环很有用,例如 for x in "$@"
。如果您正在从外部命令或文件中读取内容,您通常需要一个 while read
循环。
替代方案不使用 shell
逐行处理文件时,通常可以使用 sed 或 awk 更有效地实现目标。作为使用 awk 的例子,上面的循环简化为:
$ awk '{print "this is ftype " [=11=]}' filetypes
this is ftype *.txt
this is ftype *.sh
echo $(cat foo)
将生成 foo
的内容,将它们拆分为单词,对每个单词进行 globs - 即,将 foo
的内容视为参数 - 然后将其插入当前命令行。
echo "$(cat foo)"
会将 foo
的内容作为单个参数生成,不将它们视为参数,不会 glob(但你只会通过循环一次)。
您想一次阅读 foo
一行;为此使用 while read -r ftype
。