我一直在阅读LPIC-1 学习指南。
echo "This is a sentence. " !#:* !#:1->text3
我无法理解上面的代码行如何echo
多次重复该命令。我知道它正在使用 的历史功能bash
,但我找不到 !#:*
或 的任何文档!#:1
。有人能为我解释一下吗?
答案1
是的,这就是利用历史。
!#
是一个历史事件指示符
这是指到目前为止输入的整个命令行。
:*
是一个单词(范围)指示符,指的是除第 0 个单词之外的所有单词。因此,在您输入 后echo "This is a sentence. "
,然后!#:*
会扩展为"This is a sentence. "
。并且(其中x-y
X和y是整数)是指字数的字(范围)指示符X通过字数y。如果y省略 ( x-
),这被解释为表示字数X通过倒数第二个词。因此,在“到目前为止输入的整个命令行”之后
echo "This is a sentence. " "This is a sentence. "
然后!#:1-
扩展为"This is a sentence. "
,因为每个带引号的"This is a sentence. "
字符串都算作一个单词,因此!#:1-
相当于!#:1
(仅单词编号 1)。所以你最终会得到
echo "This is a sentence. " "This is a sentence. " "This is a sentence. " >text3
事实上,the-
和 the>
同时出现在命令中只是一种混淆;他们不互动。以及“这是一个句子”这一事实。被引用掩盖了正在发生的事情;如果你说
echo This is a sentence. !#:* !#:1-
它将扩展到
echo This is a sentence. This is a sentence. !#:1-
然后到
echo This is a sentence. This is a sentence. This is a sentence. This is a
(因为!#:1-
扩展到单词 1 到倒数第二个单词。)
答案2
您可以找到 Peter Krumins 撰写的关于 bash 历史备忘单的好文档这里。
既然你明白了!#
,那我们就解释一下:*
和:1
。
*
:指除第零个之外的所有单词。x-
:指从 x 到倒数第二个单词的单词。
所以你的命令:
echo "This is a sentence. " !#:* !#:1-
!#:*
获取除第零个之外的所有内容,因此得到"This is a sentence. "
,你的命令变为echo “这是一个句子。” 这是一个句子。 ”。!#:1-
从 1 到第二个单词到最后一个单词,这意味着"This is a sentence. "
您的命令变为echo “这是一个句子。” “这是一个句子。” “这是一个句子。”
答案3
正如 @glennjackman 指出的,这一切都包含在 bash 手册中。在手册页中搜索HISTORY EXPANSION
.
!#
是一个事件指示符意思是“到目前为止输入的整个命令行”。在您的示例中echo "This is a sentence. "
,包括最后一个双引号后的尾随空格。:
分隔开事件指示符(!#
) 来自词指示符(*
)。*
是一个词指示符意思是“事件中除了第零个词之外的所有词”
所以echo "This is a sentence. " !#:*
扩展到
echo "This is a sentence. " "This is a sentence. " $
(美元符号是我的,表示空白的结尾)这与
This is a sentence. This is a sentence. $
到终端(同样,美元符号是我的,表示空白结束)。
第二事件指示符:词指示符pair ( !#:1-
) 以类似的方式运行(但请记住,它必须处理这样一个事实:既然第一个指示符对已被求值,命令行已大大扩展)。
答案4
我已经尝试过!#:*
和!#:1
。我在网上找不到很多资源,但我确信您引入了一个echo "Sample text"
然后您可以使用!#:* !#:1 !#:2->text
!#:* 将临时将字符串内容存储在那里。我不确定这是否是一种条件语句,因为我无法找到太多资源,但当您尝试编写相同的内容并希望节省击键次数时,这似乎很有用。我在 bash 中尝试过:
echo "test" !#:* !#:1 !#:2 !#:3 !#:4->test1
这是我在 test1 中得到的结果:
test test test test test test
非常漂亮的工具。