【问题标题】:How to cut an existing variable and assign to a new variable in bash如何在bash中剪切现有变量并分配给新变量
【发布时间】:2017-11-22 05:34:33
【问题描述】:
!/bin/bash
VAR=$(some curl commands)
token =$(cut -c 18-53 $VAR)
echo $token

我想在我的 cut 命令中使用 VAR 变量,但是当我这样使用时,它会说;

No such file or directory

我只想将 VAR(curl 命令的输出)从 18.char 削减到 53.char。有什么建议吗?

【问题讨论】:

  • 你不能在token=之间放置空格
  • 老实说,我没有看到 $VAR 被用于 cut 任何地方
  • 转到您的终端,输入man bash,搜索参数扩展部分,然后查找${parameter:offset:length}。这称为“子字符串扩展”,并且有很好的记录。
  • "out" 应该是 "$VAR"。当我尝试 txt 文件时,我忘记了
  • # 中的 #!/bin/bash 很重要。您当前的 shebang 通常会导致脚本文件由与 Bash 不兼容的 csh 执行。

标签: linux bash


【解决方案1】:

让我们定义一个例子var

$ var='The quick brown fox jumped over the lazy dog on the way to the market'

现在让我们使用 cut 选择字符 18 到 53:

$ echo $(cut -c 18-53 <<<"$var")
ox jumped over the lazy dog on the w

因为cut 期望从标准输入(如果不是文件)读取,我们使用&lt;&lt;&lt; 告诉bash 在标准输入上提供$var 的内容。这被称为 这里的字符串

或者,我们可以单独使用 bash 选择相同的字符:

$ echo ${var:17:36}
ox jumped over the lazy dog on the w

构造${var:17:36} 称为子字符串扩展。它从位置 17 开始选择 36 个字符。(在 bash 中,与 cut 不同,第一个字符编号为零。)

我们当然可以将选中的字符串赋值给一个变量:

$ token=${var:17:36}
$ echo "$token"
ox jumped over the lazy dog on the w

或者:

$ token=$(cut -c 18-53 <<<"$var")
$ echo "$token"
ox jumped over the lazy dog on the w

POSIX

以上命令在 bash 中工作。如果我们想要移植到 POSIX shell,那么我们既不能使用 子字符串扩展,也不能使用 here 字符串。相反,正如Gordon Davisson 指出的那样,我们可以使用:

$ echo "$var" | cut -c 18-53
ox jumped over the lazy dog on the w

或:

$ token=$(echo "$var" | cut -c 18-53)
$ echo "$token"
ox jumped over the lazy dog on the w

gniourf_gniourf 提出了另一种 POSIX 方法,这个方法避免了外部进程:

$ printf '%.36s\n' "${var#?????????????????}"
ox jumped over the lazy dog on the w

cut 和 bash 子串扩展的比较

正如David C. Rankin 在 cmets 中指出的那样,使用 bash 的内部字符串处理有很大的优势。一是使用 bash 的内部命令可以避免产生额外的子 shell 和可执行文件。如果在循环中生成额外的子shell,则会极大地影响性能。

此外,命令替换具有从其输出中删除尾随换行符的副作用。这可能会导致不必要的意外。使用 bash 的内部字符串处理可以避免这种副作用。

【讨论】:

  • 使用 字符串索引 而不是 命令替换cut 的好处是您可以避免使用 bash 提供的内置功能生成额外的子shell .如果在循环中生成了额外的子shell,这会极大地影响性能。 (@Jon1024 - 我知道你知道,这只是为了 OP 的利益)
  • 只是为了澄清为什么原始版本不起作用:cut 期望其参数是要读取的 文件名,而不是要操作的字符串。 John1024 的版本做了什么 not 给它一个文件名(cut 隐含地将其视为对其标准输入而不是常规文件进行操作的含义),然后使用“here-string”来将字符串传递给cut 的标准输入。更传统的方法是 echo "$var" | cut -c 18-53 - 这甚至更慢,但可以在 bash 以外的 shell 中工作。
  • @DavidC.Rankin 好点!谢谢你。我已将其添加到答案中。
  • @GordonDavisson 也不错!我已将您的 POSIX 版本添加到答案中。
  • 请注意 cut 在行上工作(除非 GNU cut-z 选项一起使用,然后在空分隔的字段上工作)。因此,如果变量可能包含换行符(并且您确实想要完整变量的子字符串),则 cut 解决方案是不可行的。 POSIX 方式可以是printf 和参数扩展的组合:printf '%.36s\n' "${var#?????????????????}"(当然,? 的长链可以通过编程方式生成)。但是你很高兴这个问题被标记为bash
猜你喜欢
  • 1970-01-01
  • 2014-07-03
  • 2012-01-28
  • 1970-01-01
  • 2021-05-31
  • 2017-09-23
  • 2017-11-02
  • 1970-01-01
  • 2015-03-17
相关资源
最近更新 更多