我试图找到一种方法来删除一个数组中每个元素的所有换行符。我试着用一个for循环来做这件事。 字符串看起来像这样(总是三个数字,用点分开)。 "14.1.3/n",我需要去掉结尾的换行。 这就是我试图做的。 作为一个单行的

for i in ${backup_versions[*]}; do backup_versions[$i]=echo "$i" | tr '\n' ' ' ; done

更容易阅读

for i in ${backup_versions[*]}; 
 backup_versions[$i]=echo "$i" | tr '\n' ' ' 

我想我试图用错误的语法来重新分配元素,但我试过我自己发现的或知道的各种写作方法。 删掉换行的做法很好,只是重新分配是我的问题。

5 个评论
顺便提一下,根据你创建数组的方式,从开始删除尾部分隔符可能会更容易。例如,mapfile有一个专门的t开关用于此。
地图文件是用来填充这个数组的,但是尽管我使用了-t标志,新行还是没有消失。我不得不从一个S3 Bucket中读入字符串,其中充满了元数据。所以我用awk只得到一列,但我还是要去掉换行^^。
由于你没有引用${backup_versions[*]},当你访问$i时,换行应该已经被删除。
你需要使用$(...)来将命令的结果分配给一个变量。
arrays
linux
bash
shell
Thanatos-Delta
Thanatos-Delta
发布于 2021-08-24
3 个回答
Barmar
Barmar
发布于 2021-08-24
已采纳
0 人赞同

如果字符串总是这种形式,并且不包含任何空格或通配符,你可以直接使用shell的分词法从值中删除多余的空格字符。

backup_versions=(${backup_versions[*]})

如果你使用mapfile来创建数组,你可以使用-t选项来防止它首先在值中包括换行。

好吧,这个方法是迄今为止最好的,它摆脱了换行和每个元素末尾的空白。所以问题不在于我的地图文件的输入,我在某个地方读到,地图文件在每个元素的末尾都默认设置了一个空白和下一行。这是正确的吗?而分词对我来说是新事物,但刚读过一篇文章,很有意思。谁能推荐一些关于这个问题的文章或其他类型的信息?谢谢,真的。
替换代码1】的-t选项将删除每行的尾部分隔符。
Léa Gris
Léa Gris
发布于 2021-08-24
0 人赞同

使用Bash的字符串替换扩展${var//old/new}来删除所有的换行符,并动态地创建一个新数组的声明,其中的元素都被删除了换行符。

#!/usr/bin/env bash
backup_versions=(
  $'foo\nbar\n'
  $'\nbaz\ncux\n\n'
  $'I have spaces\n and newlines\n'
  $'It\'s a \n\n\nsingle quote and spaces\n'
  $'Quoted "foo bar"\n and newline'
# shellcheck disable=SC2155 # Dynamically generated declaration
declare -a no_newlines="($(
  printf '%q ' "${backup_versions[@]//$'\n'/}"
# Debug print original array declaration
declare -p backup_versions
# Debug print the declaration of no_newlines
declare -p no_newlines
  • declare -a no_newlines="($(: Creates a dynamically generated declaration for the no_newlines array.
  • printf '%q ': Print each argument with quotes if necessary and add a trailing space.
  • "${backup_versions[@]//$'\n'/}": Expand each element of the backup_versions array, // replacing all $'\n' newlines by nothing to delete them.
  • 最后,no_newlines数组将包含backup_versions的所有条目,并去掉新行。

    调试输出符合预期。

    declare -a backup_versions=([0]=$'foo\nbar\n' [1]=$'\nbaz\ncux\n\n' [2]=$'I have spaces\n and newlines\n' [3]=$'It\'s a \n\n\nsingle quote and spaces\n' [4]=$'Quoted "foo bar"\n and newline')
    declare -a no_newlines=([0]="foobar" [1]="bazcux" [2]="I have spaces and newlines" [3]="It's a single quote and spaces" [4]="Quoted \"foo bar\" and newline")
        
    替换代码0】在这里真的有效吗?引号在扩展变量后不会被解析。
    @Barmar 是的 %q可以工作,如果元素包含空格或引号或任何需要转义或引号的东西,则有必要。使用printf的子壳调用会生成一个声明。
    Gordon Davisson
    Gordon Davisson
    发布于 2021-08-24
    0 人赞同

    你可以在扩展数组时使用一个修改器,然后保存修改后的内容。如果元素只是有一个尾部的换行,可以使用去除子串 to trim it:

    backup_versions=("${backup_versions[@]%$'\n'}")