≡菜单

包含15个示例的Ultimate Bash Array教程

数组是一个包含多个值的变量,这些值可以是相同类型或不同类型。没有最大的数组大小限制,也没有要求成员变量被连续索引或连续分配。数组索引从零开始。

在本文中,让我们回顾bash中的15种不同的数组操作。

本文是正在进行的一部分 Bash教程 系列。对于那些不熟悉bash脚本的人,请从 Bash脚本介绍教程.

1.声明一个数组并赋值

在bash中,使用以下格式的变量时会自动创建数组,

name[index]=value
  • 名称是数组的任何名称
  • index could be any number 要么 expression that must 评估uate to a number greater than 要么 equal to zero.You can declare an explicit array using 声明-a arrayname.
$ cat arraymanip.sh
#! /bin/bash
Unix[0]='Debian'
Unix[1]='Red 帽子'
Unix[2]='Ubuntu'
Unix[3]='Suse'

echo $ {Unix [1]}

$./arraymanip.sh
Red 帽子

要从数组访问元素,请使用大括号,例如$ {name [index]}。

2.在声明期间初始化数组

不必单独初始化数组的每个元素,而是可以通过使用大括号指定元素列表(由空格分隔)来声明和初始化数组。

Syntax:
声明-a arrayname =(element1 element2 element3)

如果元素具有空格字符,请用引号将其引起来。

#! /bin/bash
$cat arraymanip.sh
declare -a 的Unix=('Debian' 'Red 帽子' 'Red 帽子' 'Suse' 'Fedora');

声明-a声明一个数组,括号中的所有元素都是数组的元素。

3.打印整个Bash阵列

有多种方法可以打印数组的整个元素。如果索引号是@或*,则引用数组的所有成员。您可以使用bash中的循环语句遍历数组元素并进行打印。

回声 $ {Unix [@]}

# Add the above 回声 statement into the arraymanip.sh
#./t.sh
Debian Red 帽子 的Ubuntu 苏塞

在不提供索引号的情况下引用数组的成员变量的内容与引用第一个元素的内容相同,第一个元素的索引号为零。

4. Bash阵列的长度

我们可以使用称为$#的特殊参数来获取数组的长度。

$ {#arrayname [@]}为您提供数组的长度。

$ cat arraymanip.sh
declare -a 的Unix=('Debian' 'Red 帽子' 'Suse' 'Fedora');
echo ${#Unix[@]} #Number of elements in the array
echo ${#Unix}  #Number of characters in the 科幻rst element of the array.i.e 德比安
$./arraymanip.sh
4
6

5.数组中第n个元素的长度

$ {#arrayname [n]}应该给出数组中第n个元素的长度。

$cat arraymanip.sh
#! /bin/bash

Unix[0]='Debian'
Unix[1]='Red 帽子'
Unix[2]='Ubuntu'
Unix[3]='Suse'

echo ${#Unix[3]} # length of the element located at index 3 i.e 苏塞

$./arraymanip.sh
4

6.按数组的偏移量和长度提取

The following example shows the way to extract 2 elements starting from the position 3 from an array called 的Unix.

$cat arraymanip.sh
Unix=('Debian' 'Red 帽子' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux');
echo $ {Unix [@]:3:2}

$./arraymanip.sh
Suse 软呢帽

上面的示例返回第三个索引和第四个索引中的元素。索引始终以零开头。

7.对于数组的特定元素,使用偏移量和长度提取

从数组元素中仅提取前四个元素。例如,位于数组第二个索引的Ubuntu,可以为数组的特定元素使用offset和length。

$cat arraymanip.sh
#! /bin/bash

Unix=('Debian' 'Red 帽子' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux');
echo ${Unix[2]:0:4}

./arraymanip.sh
Ubun

上面的示例从数组的第二个索引元素中提取前四个字符。

8.搜索并替换数组元素

The following example, searches for 的Ubuntu in an array elements, 和 replace the same with the word ‘SCO 的Unix’.

$cat arraymanip.sh
#!/bin/bash
Unix=('Debian' 'Red 帽子' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux');

echo $ {Unix [@]/Ubuntu/SCO 的Unix}

$./arraymanip.sh
Debian Red 帽子 SCO 的Unix 苏塞 软呢帽 悉尼科技大学 OpenLinux的的

在此示例中,它替换了第二个索引中的元素‘Ubuntu’ with ‘SCO 的Unix’。但是此示例不会永久替换数组内容。

9.向现有的Bash数组添加元素

以下示例显示了将元素添加到现有数组的方法。

$cat arraymanip.sh
Unix=('Debian' 'Red 帽子' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux');
Unix=("$ {Unix [@]}" "艾克斯" "HP-UX")
echo ${Unix[7]}

$./arraymanip.sh
AIX

In the array called 的Unix, the elements ‘AIX’ 和 ‘HP-UX’分别添加到第七和第八索引中。

10.从数组中删除一个元素

unset用于从数组中删除元素。unset与将null分配给元素具有相同的效果。

$cat arraymanip.sh
#!/bin/bash
Unix=('Debian' 'Red 帽子' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux');

unset 的Unix[3]
echo ${Unix[3]}

上面的脚本将只打印null,这是第3个索引中可用的值。以下示例显示了从数组中完全删除元素的一种方法。

$ cat arraymanip.sh
Unix=('Debian' 'Red 帽子' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux');
pos=3
Unix=(${Unix[@]:0:$pos} $ {Unix [@]:$((($ pos + 1))})
echo $ {Unix [@]}

$./arraymanip.sh
Debian Red 帽子 的Ubuntu 软呢帽 悉尼科技大学 OpenLinux的的

在此示例中,$ {Unix [@]:0:$ pos}将为您提供3个从第0个索引开始的元素,即0,1,2,而$ {Unix [@]:4}将为您提供从第4个索引到该元素。最后索引。并合并以上两个输出。这是从数组中删除元素的解决方法之一。

11.使用模式删除Bash数组元素

在搜索条件中,您可以给出模式,并将剩余的元素存储到另一个数组中,如下所示。

$ cat arraymanip.sh
#!/bin/bash
declare -a 的Unix=('Debian' 'Red 帽子' 'Ubuntu' 'Suse' 'Fedora');
declare -a patter=( $ {Unix [@] / Red * /} )
echo ${patter[@]}

$ ./arraymanip.sh
Debian 的Ubuntu 苏塞 软呢帽

上面的示例删除了具有图案Red *的元素。

12.复制数组

展开数组元素,然后将其存储到新数组中,如下所示。

#!/ bin / bash
Unix=('Debian' 'Red 帽子' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux');
Linux=("$ {Unix [@]}")
echo ${Linux[@]}

$ ./arraymanip.sh
Debian Red 帽子 的Ubuntu 软呢帽 悉尼科技大学 OpenLinux的的

13.两个Bash数组的串联

展开两个数组的元素,然后将其分配给新数组。

$cat arraymanip.sh
#!/bin/bash
Unix=('Debian' 'Red 帽子' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux');
Shell=('bash' 'csh' 'jsh' 'rsh' 'ksh' 'rc' 'tcsh');

UnixShell=("$ {Unix [@]}" "${Shell[@]}")
echo ${UnixShell[@]}
echo ${#UnixShell[@]}

$ ./arraymanip.sh
Debian Red 帽子 的Ubuntu 苏塞 软呢帽 悉尼科技大学 OpenLinux的的 bash csh jsh rsh ksh rc tcsh
14

它打印具有两个数组元素的数组‘Unix’ 和 ‘Shell’,并且新数组的元素数为14。

14.删除整个数组

unset用于删除整个阵列。

$cat arraymanip.sh
#!/bin/bash
Unix=('Debian' 'Red 帽子' 'Ubuntu' 'Suse' 'Fedora' 'UTS' 'OpenLinux');
Shell=('bash' 'csh' 'jsh' 'rsh' 'ksh' 'rc' 'tcsh');

UnixShell=("$ {Unix [@]}" "${Shell[@]}")
unset 的UnixShell
echo ${#UnixShell[@]}

$ ./arraymanip.sh
0

取消设置数组后,其长度将为零,如上所示。

15. 将文件内容加载到数组中

您可以将文件内容逐行加载到数组中。

#Example 科幻le
$ cat 日志文件
Welcome
to
thegeekstuff
Linux
Unix

$ cat loadcontent.sh
#!/bin/bash
filecontent=( `cat "日志文件" `)

for t in "$ {filecontent [@]}"
do
echo $t
done
echo "Read 科幻le content!"

$ ./loadcontent.sh
Welcome
to
thegeekstuff
Linux
Unix
Read 科幻le content!

在上面的示例中,数组元素的每个索引均已打印出for循环。

推荐读物

Bash 101骇客,作者:Ramesh Natarajan。我大部分时间都花在Linux环境上。所以我自然’我是Bash命令行和Shell脚本的忠实拥护者。 15年前,当我从事不同口味的* nix时,我曾经在C 贝壳和Korn 贝壳上编写了大量代码。后来,当我开始以系统管理员的身份在Linux上工作时,我几乎可以使用Bash shell脚本自动化所有可能的任务。根据我的Bash经验,我’编写了Bash 101 Hacks电子书,其中包含有关Bash命令行和Shell脚本的101个实用示例。如果你’我一直在考虑精通Bash,请帮自己一个忙,阅读本书,这将帮助您控制Bash命令行和Shell脚本。

如果您喜欢这篇文章,您可能还会喜欢..

  1. 50个Linux Sysadmin教程
  2. 50个最常用的Linux命令(包括示例)
  3. 排名前25位的最佳Linux性能监视和调试工具
  4. 妈妈,我找到了! – 15个实用的Linux Find命令示例
  5. Linux 101 Hacks第二版电子书 Linux 101黑客手册

Bash 101骇客书 Sed 和 Awk 101 Hacks Book Nagios Core 3书 Vim 101黑客手册

{ 62 评论… 加一 }

  • 坦美乔希 2010年6月3日,上午5:59

    好文章。

    我是Linux的新手,并且会非常关注您的文章。
    只是想确认以下行是否是显示代码或自己显示的句子中的错字
    “声明-a声明一个数组,大括号中的所有元素都是数组的元素” –我们在使用大括号还是括号?

    谢谢,
    坦美

  • 加布里埃 2010年6月3日,上午6:47

    好东西!!!
    问候

    加布里埃

  • 亚姆布赖恩 2010年6月3日,上午8:52

    很好的例子-

    尽管由于OpenLinux数组实体缺少结尾的单引号(您知道这会引发错误),所以对6进行了更正。

    保持良好的工作

  • 拉梅什·纳塔拉詹(Ramesh Natarajan) 2010年6月3日,晚上10:11

    @ 坦美,@ Bryan,

    感谢您指出问题。现在已修复。

  • 哈里 2010年6月3日,晚上11:50

    最好的

    最好

  • 克里斯·约翰逊 2010年6月4日,上午8:01

    1. “echo $ {Unix [1]}”不一定会从数组中打印元素1。例如:

    $ 的Unix[1]=” AAA BBB CCC”
    $ 回声 $ {Unix [1]}
    AAA BBB CCC

    Leading 和 trailing whitespace will be lost, 和 consecutive whitespace will be 红uced to a single 空间.

    它应该是:

    回声 “${Unix[1]}”

    (几乎所有示例都显示相同的错误,因为未引用变量引用。错误是否在输出中明显取决于数组元素的内容。)

    2. “declare -a” is unnecessary

    3. “echo $ {Unix [@]}”与#1有相同的问题

    4.更准确地说,$ {#arrayname [@]}为您提供数组中元素的数量。

    9.从bash3开始,元素还可以附加到带有“+=”:

    的Unix+=( “AIX” “HP-UX” )

    15. 科幻lecontent =(`cat“logfile” `)

    更有效率’需要一个外部命令,是:

    科幻lecontent =(`< "logfile" `)

    (请注意:'t逐行读取文件;它逐字读取。在一行上有多个单词的文件上进行尝试。)

    从bash4开始,使用内置的mapfile可以更有效地完成此操作:

    映射文件-t文件内容< "$logfile"

    对于"${filecontent[@]}"

    循环不是必需的:

    打印"%s\n" "${filecontent[@]}"

  • 匿名 2010年6月4日,晚上10:01

    请注意,该示例不会将以下文件读入数组(其中每一行都是一个元素)。
    这是第一行
    这是第二行
    这是最后一行
    要将文件(作为行)读入数组,请执行以下操作:
    {
    IFS = $’\n’
    array_name =($(猫文件名))
    }
    注意使用“{”在此示例中,无需更改并保存IFS值即可。

  • 2010年6月7日,上午9:36

    我喜欢它!展示简单用例的好例子。

    可悲的是,Bash中数组的语法对我来说太复杂了,所以我’我会和Perl在一起。您多久听到一次? - 一世’Perl不在时我可能会回到这里’出于某种原因允许在系统上使用。

  • 巴吉诺夫 2010年6月9日,上午4:47

    简直太棒了!谢谢!

  • 2010年6月21日,上午3:36

    当您这样做时:

    科幻lecontent =(`cat“ 日志文件”`)

    和日志文件有一个“*”您会在目录中找到档案列表,我该如何解决?

    谢谢

  • 克里斯·约翰逊 2010年6月21日,上午11:34

    是的,执行此操作时,$ 日志文件仅包含一个星号(*)。

    如果要显示该星号,则必须引用变量引用,否则通配符将被展开:

    打印“%s\n” “$logfile”

    要么:

    回声 “$logfile”

    (除非有充分的理由,否则总是引用变量引用。)

  • 托尼·库库(Toni Kukul) 2010年10月8日,下午5:47

    要将文件读入数组’可以使用readarray或mapfile bash内置函数。
    读数组< 科幻lename
    要么
    映射文件< 科幻lename

    File is 读into MAPFILE variable 通过 定义ault.

  • 安德森·文图里尼(Anderson Venturini) 2012年2月28日,上午6:08

    非常感谢!很棒的教程!这非常有用!恭喜!

  • ak 2012年3月11日,上午10:50

    很好的例子。感谢您的辛勤工作和清晰的解释。错误编号12:从复制的数组中省略了Suse。

  • 维维克 2012年5月30日,晚上8:07

    你好

    我需要在Shell脚本中使用cntrC。这是一个例子:

    运行一些命令
    电脑
    运行更多命令

    如何在不键入cnrlC的情况下让我的shell脚本生成cntrC?

    维维克。

  • 克里斯·约翰逊 2012年5月31日,下午12:21

    维维克,您真正想做什么?

  • 维维克 2012年5月31日,晚上8:54

    克里斯,我需要运行一个脚本,该脚本的命令给出正在运行的输出。我需要将该命令的参数例如从1更改为10。
    例:
    为$(seq 1 10)

    完成

    现在给出运行的输出。
    现在,当a = 1时,命令正在运行。
    我想将cntrlC发送到命令,以便在说100秒后开始并结束。

    维维克。

  • 克里斯·约翰逊 2012年6月1日,下午12:23

    维维克,这与数组有什么关系?

    为{1..10}中的n

    : 随你
    完成&

    读&& kill “$!”

  • 丹尼斯·达什科维奇 2012年7月12日,下午3:09

    更准确地说,数组中第N个元素的长度将给出带有N-1索引的语句,即$ {#arrayname [N-1]}。

    感谢您的教程!它’s really great!

  • h 2012年10月29日,上午1:25

    即使使用引号也不会消除元素中的空白

  • 乔希 2013年1月2日,下午5:41

    怎么样“测试以查看值是否在数组中” example?

    以下是实现此目的的一个小功能。搜索字符串是第一个参数,其余的是数组元素:

    containsElement(){
    本地电子
    为e in“${@:2}”; 做 [[ “$e” == “$1” ]] && return 0; 完成
    返回1
    }
    该函数的测试运行可能类似于:

    $ array =(“要寻找的东西” “a string” “test2000”)
    $ containsElement“a string” “${array[@]}”
    $ 回声 $?
    0
    $ containsElement“blaha” “${array[@]}”
    $ 回声 $?
    1

  • 克里斯·约翰逊 2013年1月2日,晚上7:23

    乔希,在那里’不需要循环:

    arraycontains()#@用法:arraycontains STRING ARRAYNAME [IFS]
    {
    本地字符串= $ 1数组= $ 2本地数组IFS = $ {3:-:}
    评估 “localarray=( \”\${$array[@]}\” )”
    案件“$ IFS $ {localarray [*]} $ IFS” in
    *”$IFS$string$IFS”*) return ;;
    *)返回1 ;;
    埃萨克
    }

  • 克里斯·约翰逊 2013年1月8日,下午6:41

    我在发布了许多用于处理数组的函数 http://cfajohnson.com/shell/arrays/

  • 安杰洛 2013年1月23日,上午6:32

    作为历史记录:SuSE具有小写字母“u”其余为大写,因为它最初代表“软件与系统”, meaning “软件和系统开发”. (Ref: http://en.wikipedia.org/wiki/SuSE)

  • 安杰洛 2013年1月23日,上午9:34

    I’我喜欢清晰易读的代码,但对约翰逊先生是否好奇感到好奇’与Josh相比,s arraycontains方法具有效率优势(尽管其本质更加模糊)’s(几乎完全是我一直使用的方法)。我可以’根本无法发挥作用。也许我’我错过了一些东西,但万一我’并非如此,也许我可以省掉别人走这条路的浪费精力。

    这是我对克里斯·约翰逊的考验’s code:

    #!/ bin / bash
    arraycontains(){#@用法:arraycontains STRING ARRAYNAME [IFS]
    本地字符串= $ 1数组= $ 2本地数组IFS = $ {3:-:}
    评估 “localarray=( \”\${$array[@]}\” )”
    案件“$ IFS $ {localarray [*]} $ IFS” in
    *”$IFS$string$IFS”*) return ;;
    *)返回1 ;;
    埃萨克
    }

    回声 -en “String 测试 1: ”
    一个=(“and” “this” “is” “another” “test”)
    如果数组包含“something” “${one[@]}”
    然后
    回声 “正确,但应为FALSE”
    其他
    回声 “OK”
    科幻

    回声 -en “String 测试 2: ”
    如果数组包含“another” “${one[@]}”
    然后
    回声 “OK”
    其他
    回声 “否,但应为TRUE”
    科幻

    回声 -en “Numeric 测试: ”
    两个=(1 2 3 4 5)
    数组包含“5” “${two[@]}”
    回声 $?

    回声 -en “带引号的数字测试:”
    三=(“1” “2” “3” “4” “5”)
    数组包含“6” “${three[@]}”
    回声 $?

    这是输出:

    $ sh 测试-contains.sh
    String 测试 1: OK
    字符串测试2:FALSE,但应为TRUE
    数值测试:./ 测试-contains.sh:第4行:$ {1 [@]}:错误替换
    1
    带引号的数字测试:./ 测试-contains.sh:第4行:$ {1 [@]}:错误的替换
    1

    除了在传递数值数组时给出错误消息外,它总是返回FALSE(1)。经调查,我发现“eval”线路不工作; localarray始终为空(因此也难怪它总是返回false)。

    我使用BASH 3.00.16和4.2.20运行了此脚本,并得到了相同的结果。

  • Heriel Uronu @ udom 2013年4月30日,上午7:18

    是的…在Linux命令中对数组进行了很好的说明。
    wel 完成stay blessed,

  • x31当量 2013年7月17日,上午10:49

    The second part of Example 10 is especially wrong because of the quoting issue. It means $ {Unix [1]} is Red instead of Red 帽子. The correct way is

    的Unix=(“${Unix[@]:0:$pos}” “$ {Unix [@]:$((($ pos + 1))}”)

  • 汉斯 2013年11月29日,下午1:49

    我找到的关于Bash阵列的最佳指南!

    谢谢。

  • 杯子896 2014年1月2日,上午6:31

    要将文件读取为数组中的行,请使用双引号

    科幻leContents =(“$(cat sunflower.html)” )

    用于行进“${fileContents[@]}”

    回声 “$line”
    完成

  • 克里斯·约翰逊 2014年1月2日,上午11:57

    杯子896,
    那不会逐行读取文件;它将逐字阅读。文件中的所有空格都将用作分隔符。

    而你不’需要循环以打印出数组:

    打印‘%s\n’ “${fileContents[@]}”

  • 克里斯·约翰逊 2014年1月2日,下午2:10

    我的错,杯子896;您的代码会将文件读入数组的单个元素。您可以通过以下方式看到它:

    打印‘%s\n’“ $ {fileContents [0]}”

    如果你做了

    科幻leContents =($(cat sunflower.html))##无引号

    它将每个单词读入数组的单独元素中。

  • Offirmo 2014年1月9日,上午8:21

    很好,但是“数组迭代” is missing !

  • 埃里克 2014年1月24日,下午5:43

    非常感谢!

  • 罗伯特·维拉 2014年2月23日,晚上10:57

    如果bash脚本不执行该怎么办’t accept arrays?

    错误讯息:
    >>>> “declare: not found”
    要么
    >>>> “Unix [0] = Debian:找不到”

  • 克里斯·约翰逊 2014年2月25日,下午3:14

    Robert,请确保您使用bash解释脚本。

  • 罗伯特·马克·布拉姆 2014年2月27日,晚上8:00

    您的第二个例子“10.从数组中删除一个元素”是错误的,因为您没有将数组部分用引号引起来– so ‘Red Hat’成为两个要素。

    在这里用样张固定。

    2月28日星期五– 12:53 PM > 的Unix=(‘Debian’ ‘Red 帽子’ ‘Ubuntu’ ‘Suse’ ‘Fedora’ ‘UTS’ ‘OpenLinux’);
    2月28日星期五– 12:53 PM > 回声 ${#Unix[@]}
    7
    2月28日星期五– 12:53 PM > pos=3
    2月28日星期五– 12:53 PM > 回声 ${Unix[$pos]}
    苏塞
    2月28日星期五– 12:53 PM > 的Unix=(“${Unix[@]:0:$pos}” “$ {Unix [@]:$((($ pos + 1))}”)
    2月28日星期五– 12:53 PM > 回声 ${Unix[$pos]}
    软呢帽
    2月28日星期五– 12:53 PM > 回声 $ {Unix [@]}
    德比安 Red 帽子 的Ubuntu 软呢帽 悉尼科技大学 OpenLinux的的
    2月28日星期五– 12:53 PM > 回声 ${#Unix[@]}
    6
    2月28日星期五– 12:53 PM > for index in “${!Unix[@]}” ; 做 打印“%4d: %s \ n” $index “${Unix[$index]}” ;完成
    0: 德比安
    1: Red 帽子
    2: 的Ubuntu
    3: 软呢帽
    4: 悉尼科技大学
    5:OpenLinux的的

  • 伊恩·弗莱明 2014年3月13日,下午12:37

    另一种可能更简单的删除元素的方法是从数组中的其余元素(取消设置后)重新分配Unix(确保按照上一篇文章的引号):
    unset 的Unix[2]
    的Unix=( “${Unix[@]” )

    例:
    —– $ 的Unix=(‘Debian’ ‘Red Hat’ ‘Ubuntu’ ‘SuSE’);
    —– $ 回声 “len: ${#Unix[@]}”; for ((i=0;i<4;i++)); 做 打印"%d %s \ n" $i "${Unix[$i]}"; 完成
    len:4
    0 德比安
    1 红帽
    2 的Ubuntu
    3 苏斯
    —– $ unset 的Unix[2]
    —– $ 回声 "len: ${#Unix[@]}"; for ((i=0;i<4;i++)); 做 打印"%d %s \ n" $i "${Unix[$i]}"; 完成
    len:3
    0 德比安
    1 红帽
    2
    3 苏斯
    —– $ 的Unix=( "${Unix[@]}" )
    —– $ 回声 "len: ${#Unix[@]}"; for ((i=0;i<4;i++)); 做 打印"%d %s \ n" $i "${Unix[$i]}"; 完成
    len:3
    0 德比安
    1 红帽
    2 苏斯
    3

    (请注意,缩短循环后,我的循环会越过数组的结尾)

  • 乔佩罗 2014年4月15日,下午5:43

    >>>There is no “DECLARED”数组大小的最大限制,…..

  • 乔佩罗 2014年4月16日,下午3:03

    我需要报价,不要’t you?
    的Unix=( “${Unix[@]:0:$pos}” “$ {Unix [@]:$(($ pos + 1)” )})

  • 乔佩罗 2014年4月16日,下午3:24

    也。在11
    声明-a patter =(“${Unix[@]/Red*/}” )
    它没有’t删除数组元素,它将删除数组中每个元素内满足正则表达式的第一个匹配项。

  • 2014年5月19日,下午2:01

    乔佩罗,实际上:
    声明-a patter =(“ $ {Unix [@] / Red * /}”)
    删除满足数组中每个元素内的正则表达式的所有匹配项。

    $ 的Unix=(‘Debian’ ‘Red 帽子’ ‘Red Hat 2’ ‘Red Hat 3’ ‘Ubuntu’ ‘Suse’ ‘Fedora’ ‘UTS’ ‘OpenLinux’);

    $ patter=( $ {Unix [@] / Red * /} )

    $ 回声 ${patter[@]}
    德比安 的Ubuntu 苏塞 软呢帽 悉尼科技大学 OpenLinux的的

  • 小宁 2014年6月14日,下午1:25

    感谢您的精彩教程!

    我有一个txt文件,其中列出了我希望CD进入的目录列表,并对所有目录进行相同的处理。假设它看起来像这样:

    “/path/to/first/dir”
    “/path/to/second/dir”
    “/ path / to / third / dir /带空格”

    我尝试将示例15中的代码用于我的目的:

    #!/ bin / bash
    DIR =(`猫“$ HOME / path / to / txt.txt” `)
    对于“${DIR[@]}”

    回声 “$t”
    完成
    回声 “Done!”

    上面的脚本在第一个目录和第二个目录下工作正常,但是第三个目录将输出以下内容:

    “/ path / to / third / dir / with
    空间”

    而不是一行。我该如何解决?

    另外,如果我在上面的脚本中添加cd命令:

    #!/ bin / bash
    DIR =(`猫“$ HOME / path / to / txt.txt” `)
    对于“${DIR[@]}”

    回声 “$t”
    cd “$t”
    完成
    回声 “Done!”

    所有cd命令都将失败,输出如下所示:

    “/path/to/first/dir”
    测试.sh:第6行:cd:“/path/to/first/dir”: 无此文件或目录
    “/path/to/second/dir”
    测试.sh:第6行:cd:“/path/to/second/dir”: 无此文件或目录
    “/ path / to / third / dir / with
    测试.sh:第6行:cd:“/ path / to / third / dir / with: 无此文件或目录
    空间”
    测试.sh:第6行:cd:space”: 无此文件或目录

    您能否阐明为什么会发生这种情况以及如何解决?非常感谢你!

  • 克里斯·约翰逊 2014年6月19日,晚上8:45

    >>DIR =(`cat“ $ HOME / path / to / txt.txt”`)

    这始终是读取文件的错误方法。它逐字读取而不是逐行读取。

    在bash4中,简单的方法是使用mapfile:

    映射文件-t目录< "$filename"

  • 小宁 2014年6月20日,上午7:06

    克里斯,你好

    感谢您的答复!

    我更改了代码以使用您建议的mapfile行。

    但是当我运行脚本时,这就是我得到的:

    ./test.sh:第3行:mapfile:找不到命令

    有任何想法吗?谢谢!

  • 伊恩·弗莱明 2014年6月20日,下午4:12

    最近遇到的问题是将一些脚本从RedHat移植到Apple OS X Mavericks。并非全部’支持mapfile(又名readarray);它’在RedHat中,但在Apple中不存在’s OS X. type “man mapfile” ; if it says “No manual entry”那么您的系统可能没有’没有实现mapfile。在这种情况下,您可能需要执行以下操作(比我聪明的人可能会提供更好的解决方案):

    i = 0
    边读边

    dir [$(((i ++))] = $ line#将$ line存储在dir [$ i]中并递增$ i
    。 。 。
    完成< $ HOME / path / to / txt.txt

  • 克里斯·约翰逊 2014年6月20日,下午5:00

    mapfile是在bash4中引入的-已有5多年了。

    升级你的bash;它’s long overdue.

  • 小宁 2014年6月20日,晚上8:16

    我只是在Mac OS X Mavericks中检查bash版本:
    GNU bash版本4.3.11(1)-发行版(x86_64-apple-darwin13.1.0)

    它应该有mapfile吗?

  • 小宁 2014年6月20日,晚上8:22

    我还尝试了Ian建议的读取行方法。谢谢伊恩顺便说一句!

    但是,我仍然遇到了一个问题“echo”命令给出了正确的结果,但是我可以’cd进入所有目录。

    重击返回:“./test.sh:第14行:cd​​:“/用户/小宁/一些/路径”: 无此文件或目录”

  • 伊恩·弗莱明 2014年6月20日,晚上10:57

    Bash 4.3.xx确实有mapfile。但是,OS X Mavericks’bash的版本应位于/ bin / bash中,为3.2.xx。我怀疑您已经安装了bash的第二个版本,并且它正在作为启动外壳程序被调用。 (一个可能的位置是/ opt / local / bin / bash,如果macports安装的任何程序需要的话,这是macports进行安装的位置。Fink可以这样做。)

    您报告的bash版本4.3应该具有mapfile,但在OS X下没有/ bin / bash,并且您的脚本指定在/ bin / bash(脚本的第一行)下运行。要在脚本中使用4.3,请找到运行bash的位置(“which bash”可能会告诉您),并更改脚本的第一行以调用该bash。例如(使用我的示例):

    #!/ opt / local / bin / bash

    关于为什么您的脚本无法CD到“ / Users / xiaoning / some / path”,假设“ / Users / xiaoning / some / path”确实存在,我没有很好的解释。命令

    ls -ld “/用户/小宁/一些/路径”

    (从命令行)将验证目录是否存在。

  • 王小宁 2014年6月21日,上午11:53

    更改#!后,mapfile现在可以工作了!行到我已安装的macport bash。

    这些都是我通常可以ls或cd进入的有效目录。但是脚本由于某种原因仍然无法正常工作…

    我的剧本’现在使用的是直接将目录数组存储在变量中,并且效果很好。但是,当我尝试从文件中读取相同的数组时,它’不再工作。很奇怪…

  • 直流电 2014年8月8日,上午10:11

    如何从多个文件中删除包含字符串数组中的任何一个的行?

  • 吉姆 2014年10月28日,上午1:28

    使用sed,编写一个使用文件名和模式的脚本来执行以下操作。
    如果文件中存在给定的模式,并且下一行以相同的模式开始和结束,则删除以给定的模式开始和结束的行。请帮忙

  • 伊夫·B 2015年4月24日,上午7:02

    感谢提示15。“将文件内容加载到数组中”。正是我想要的。

  • 约翰·阿瑟普 2015年6月1日,上午4:56

    一般而言,尤其是在使用数组时,需要特别注意引号。以下是一个简单的bash脚本,它收集了您上面演示的内容的工作示例。请注意,最后使用的文件hx仅包含几行文本,其中一些包含空格。

    #!/ bin / bash

    声明-a A
    A [3] =轻浮
    回声 “$A[3]”可能是轻浮,第三项,但不是
    回声 “${A[3]}”应该轻柔,第三项,注意括号
    回声 “${A[@]}”是数组的内容
    回声 “${#A[@]}” is length of array
    回声 “${#A[3]}”应该是7,轻柔的长度
    回声 “${A[3]:2:3}”应该是ibb,从pos 2开始的三个字符
    回声 “${A[@]/ibb/bone}”搜索并替换每个项目
    A =(“${A[@]}” “wibble”)
    回声 A is now “${A[@]}”
    回声 now
    声明-a B=(“${A[@]}”)
    回声 Third item is “${B[3]}”
    回声 Zeroth item is “${B[0]}”
    回声 So copying arrays 这个 way 做es not preserve string keys — it reindexes
    声明-a C
    C [摆动] =摆动
    回声 “${C[wibble]}”显示键是字符串,不是连续的整数
    声明-a D
    D =(“a b c d e” “c d f t g”)
    回声 D is “${D[@]}”
    回声 Length of D is “${#D[@]}”
    回声 Length of “D[0]” is “${#D[0]}”
    回声 “D[0] is ‘${D[0]}'”
    声明-a E=( $ {D [@]} )
    回声 E is “${E[@]}”
    回声 Length of E is “${#E[@]}”
    回声 Length of “E[0]” is “${#E[0]}”
    回声 “E[0] is ‘${E[0]}'”
    声明-a F =($ {D [@] / a * /})
    回声 F is “${F[@]}”
    回声 Length of F is “${#F[@]}”
    回声 Length of “F[0]” is “${#F[0]}”
    回声 “F[0] is ‘${F[0]}'”
    声明-a G =(“${D[@]/a*/}” )
    回声 G is “${G[@]}”
    回声 Length of G is “${#G[@]}”
    回声 Length of “G[0]” is “${#G[0]}”
    回声 “G[0] is ‘${G[0]}'”
    回声 Note in the above what happens with 空间s
    回声 To concatenate two arrays, preserving 空间s, use 做uble quoting
    声明-a H =(“${A[@]}” “${D[@]}”)
    声明-a I=(${A[@]} $ {D [@]})
    回声 To delete an array use unset
    回声 I is “${I[@]}”
    我未设定
    回声 I is now “${I[@]}”
    回声 reading from a 科幻le
    px(){
    for s; 做 回声 “$s”; 完成
    }
    回声 version 1
    声明-a I=(`cat hx`)
    px “${I[@]}”
    回声 version 2
    声明-a I=(“`cat hx`”)
    px “${I[@]}”

  • 格里夫 2015年11月6日,上午11:04

    x31当量 +1’关于报价的评论。这也意味着$ {#Unix [@]}的值是错误的。如果您可以更正此问题,那就太好了。

  • 山姆 2016年4月28日,下午5:37

    我从命令输出中创建了2个数组A,B

    A =(`command1`)##包含文件名
    B =(`command2`)##这包含数据库名称

    现在我使用上述数组发出command3

    示例:解压$ A | mysql -u root -p $ B ##这里的问题是它执行了‘A’每个部分‘B’ elements

    How 做 i solve 这个?

  • 斯里尼瓦斯 2016年5月25日,晚上11:49

    你好

    我有一个项目‘red 帽子’像array [‘red 帽子’]。我想将数组从单个索引拆分为2个索引,例如array [‘red’ ‘hat’]。请给我一个解决方案

  • 斯内哈 2016年6月20日,晚上11:54

    你好

    我试图获取数组中的表值。
    假设存在一个tbl,其中col1,col2,col3具有值‘abc’, ‘def’, ‘ghi k’.
    There is a function that I use to get these values from my Table to a variable say DBVAL, which is 回声ed from the function.
    现在,我想将每个列值分配给数组的不同索引。
    当前我使用的命令是:
    声明-a arrayname = {$(function_that_gets_value_from_table))

    但是如果我这样做:
    回声 ${#arrayname[@]}
    它给出:4而不是3


    对于在“${arrayname[@]}”; 做; 回声 “$arr”; 完成
    给出:
    abc
    定义
    ‘ghi
    k’
    代替:
    abc
    定义
    吉 k

    甚至:
    arrayname =($ DBVAL)
    不起作用。

    虽然,如果我用硬编码的值声明数组(而不是从函数/任何变量中获取数组),则它可以正常工作。
    声明-a arrayname =(‘abc’ ‘def’ ‘ghi k’)
    回声 ${#arrayname[@]}
    给出:3

    对于在“${arrayname[@]}”; 做; 回声 “$arr”; 完成
    给出:
    abc
    定义
    吉 k

    请帮忙。

  • 古拉布 2016年6月27日,上午7:25

    如何在运行时在数组中导入多个目录并检查目录是否存在?

  • 大卫 2016年12月27日,下午5:01

    谢谢,这对我来说是个好的开始。

  • 导航 2017年1月20日,下午2:38

    非常好!通过遵循您的示例,我已经成功地将数组用于bash中的许多不同的自动化脚本。出于同样的考虑,我现在需要将两个相同长度的不同阵列并排打印到一个文件上。换句话说,数组A的第一个元素和数组B的第一个元素应位于由制表符分隔的文本文件的第一行。等等。什么’做到这一点的最佳方法?

    我尝试了以下方法:
    打印‘%s\t%s\n’ “${A[@]}” “${B[@]}” > 科幻le.txt

    它没有’做我想做的。而是上面的命令先打印A的所有元素,然后打印B的所有元素,每行两个。

    任何指针将不胜感激!

    谢谢!
    导航

  • 安居 2017年4月8日,上午3:06

    thankuuuuuuuu

发表评论