Bash脚本 - 嵌套$(..)命令 - 无法正常工作

时间:2016-02-11 21:34:34

标签: linux bash shell sed

我试图在一行上执行这些操作/命令并将其分配给变量。除了它的一部分之外,我有90%的工作时间。

我不知道你可以做到这一点,但我读到你可以在其他$(..)中嵌套$(..)所以我试图这样做才能让这个工作,但不能似乎在剩下的路上得到了它。

基本上,我想做的是:
 1.获取文件的输出并将其分配给变量
 2.然后将一些文本预先挂起到输出的开头
 3.然后在输出的末尾附加一些文字
 4.最后删除换行符并用“\ n”字符替换它们......

我可以通过多个步骤做到这一点,但我想尝试以这种方式工作。

到目前为止,我已尝试过以下内容:

我的第一次尝试,在阅读有关嵌套的$(..):

之前
MY_VAR=$(echo -n "<pre style=\"display:inline;\">"; cat input.txt | sed ':a;N;$!ba;s/\n/\\n/g'; echo -n "</pre>")

除了在cat命令的输出和最后一个echo命令之间添加了换行符之外,这个方法有99%的工作时间。我猜这是来自cat命令,因为sed删除了除了那个之外的所有新行,也许......?

其他尝试:

MY_VAR=$( $(echo -n "<pre style=\"display:inline;\">"; cat input.txt; echo -n "</pre>") | sed ':a;N;$!ba;s/\n/\\n/g')

MY_VAR="$( echo $(echo -n "<pre style=\"display:inline;\">"; cat input.txt; echo "</pre>") | sed ':a;N;$!ba;s/\n/\\n/g' )"

MY_VAR="$( echo "$(echo -n "<pre style=\"display:inline;\">"; cat input.txt; echo "</pre>")" | sed ':a;N;$!ba;s/\n/\\n/g' )"

*大多数其他人都尝试过使用和不包含不同$(..)部分的额外双引号......

我还有其他一些尝试,但他们也没有任何运气......在上面的其他一些尝试中,它似乎有效,除了sed没有插入它的替换部分。输出在大多数情况下是正确的,除了在线之间看到“\ n”之外它只是将每条线一起粉碎成一条线而没有任何东西将它们分开......

我认为如果有人有任何想法,我会在这里找到一些小东西......?

* P.S。 Bash是否有 $(..)结构的名称?谷歌很难尝试,因为它并没有真正搜索符号......

1 个答案:

答案 0 :(得分:4)

您无需在此处嵌套命令替换。

your_var='<pre style="display:inline;">'"$(<input.txt)"'</pre>'
your_var=${your_var//$'\n'/'\n'}
  • "$(<input.txt)"扩展为input.txt的内容,但没有任何尾随换行符。 (命令替换总是剥离尾随换行符; printf '%s' "$(cat ...)"具有相同的效果,虽然效率低,因为它需要子shell,而cat ...本身则没有。)
  • ${foo//bar/baz}扩展为名为foo的shell变量的内容,bar的所有实例都替换为baz
  • $'\n'是文字换行符的bash语法。
  • '\n'是两个字符的字符串的bash语法,以反斜杠开头。
  • 因此,将所有这些绑定在一起,它首先生成一个带有前缀,文件内容和后缀的字符串;然后用&#39; \ n&#39;替换组合字符串中的文字换行符。双字符序列。

当然,这是上面实现的多行 - 但它比任何涉及命令替换的行更快,更有效。

但是,如果你真的想要一个嵌套的命令替换,你可以这样做:

your_var=$(printf '%s' '<pre style="display:inline;">' \
                       "$(sed '$ ! s/$/\\n/g' <input.txt | tr -d '\n')" \
                       '</pre>')
  • printf %s组合了它们的参数,它们之间没有任何分隔符
  • sed操作会在除最后一行
  • 之外的每一行末尾添加一个文字\n
  • tr -d '\n'操作会从文件中删除文字换行符

然而,即使这种方法可以在没有嵌套的情况下更有效地完成:

printf -v your_var '%s' '<pre style="display:inline;">' \
                        "$(sed '$ ! s/$/\\n/g' <input.txt | tr -d '\n')" \
                        '</pre>')

... printf将其结果直接分配给your_var,不需要任何外部命令替换(从而节省了外部子shell的费用)。