很抱歉问这么简单的问题,但在互联网上阅读有关此问题的信息已被证明是徒劳的。我试图更好地理解坟墓/反引号运算符,到目前为止我一直做得很好,除了一次。
假设我有一个 bash 脚本和其中的一个变量,如下所示:
var=`ls -al | grep '^...x'
现在,该脚本要求用户输入一些内容,并根据该内容输出一个结果。因此,为了避免让您对完整的脚本感到厌烦,我想将其归结为一个问题。如果用户输入“-t”作为参数,则脚本需要打印用户可以执行的所有.txt文件,即:
$var | grep '\.txt$'
现在,当我尝试重新分配 var 的值时,问题出现了。我尝试这样做:
var=`$var | grep '\.txt$'`
但这行不通。我不确定我在这里缺少什么,处理这个问题的正确方法是什么?
答案1
您应该尝试放弃使用反引号运算符来执行命令。不像使用以下内容那样便携:
$ my_var=$(ls -la | grep '^...x')
关于您的问题,请尝试
$ var=$(echo $var | grep '\.txt$')
答案2
反引号内的内容(称为命令替换顺便说一句)是要执行的命令。当你写的时候
$var | grep '\.txt$'
这会将 的值var
作为命令执行。这不是您想要的:您想要将值作为grep
命令的输入传递。基本上就是这样
echo "$var" | grep '\.txt$'
所以任务是
var=`echo "$var" | grep '\.txt$'`
我建议使用美元括号语法而不是反引号,因为引用规则更容易理解,尤其是嵌套替换:以$(
extends 开头的命令替换到匹配的)
.
var="$(echo "$var" | grep '\.txt$')"
请注意 周围的双引号$var
。该语法仅表示双引号内的$var
“”的值;var
在双引号之外,就更复杂了。看为什么我的 shell 脚本会因为空格或其他特殊字符而卡住?了解更多信息。
当心解析 的输出ls
通常是一个坏主意。它会破坏一些文件名,而且这并不是最简单的方法。如果您只想列出.txt
文件,只需使用通配符模式*.txt
(这不包括点文件,与 ; 不同ls -al
,要包含它们,请添加模式.*.txt
)。如果您只想考虑可执行的,一个可靠的方法是在循环中处理它们:
for x in *.txt; do
if [ -x "$x" ]; then
… do stuff
fi
done