bash Bash通过args选择数组元素的位置

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4386120/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 23:03:48  来源:igfitidea点击:

Bash Select position of array element by args

bash

提问by C?t?lin George Fe?til?

I want make a bash script wich return position of element array by give an arg. See code bellow , i use

我想制作一个 bash 脚本,通过给定一个参数来返回元素数组的位置。请参阅下面的代码,我使用

#!/bin/bash
args=("$@")
echo ${args[0]}
test_array=('AA' 'BB' 'CC' 'DD' 'EE')
echo $test_array
elem_array=${#test_array[@]}
for args in $test_array
do
        echo 
done

Finnally i should have output like:

最后我应该有如下输出:

$script.sh DD
4

采纳答案by jfg956

Trying to avoid complex tools:

尽量避免使用复杂的工具:

test_array=('AA' 'BB' 'CC' 'D D' 'EE')
OLD_IFS="$IFS"
IFS="
"
element=$(grep -n '^D D$' <<< "${test_array[*]}" | cut -d ":" -f 1)
IFS="$OLD_IFS"
echo $element

However, it consumes 2 processes. If we allow ourselves sed, we could do it with a single process:

但是,它消耗了2个进程。如果我们允许自己sed,我们可以用一个过程来完成:

test_array=('AA' 'BB' 'CC' 'D D' 'EE')
OLD_IFS="$IFS"
IFS="
"
element=$(sed -n -e '/^D D$/=' <<< "${test_array[*]}")
IFS="$OLD_IFS"
echo $element

Update:

更新:

As pointed out by thkala in the comments, this solution is broken in 3 cases. Be careful not to use it if:

正如 thkala 在评论中指出的那样,该解决方案在 3 种情况下被破坏。如果出现以下情况,请注意不要使用它:

  1. You want zero indexed offset.
  2. You have newlines in your array elements.
  3. And you have a sparse array, or have other keys than integers.
  1. 你想要零索引偏移。
  2. 您的数组元素中有换行符。
  3. 并且您有一个稀疏数组,或者有除整数以外的其他键。

回答by thkala

#!/bin/bash

A=(AA BB CC DD EE)

for i in "${!A[@]}"; do
        if [[ "${A[i]}" = "" ]]; then
                echo "$i"
        fi
done

Note the "${!A[@]}"notation that gives the list of valid indexes in the array. In general you cannot just go from 0 to "${#A[@]}" - 1, because the indexes are not necessarily contiguous. There can be gaps in the index range if there were gaps in the array element assignments or if some elements have been unset.

请注意"${!A[@]}"给出数组中有效索引列表的符号。一般来说,你不能只是从 0 到"${#A[@]}" - 1,因为索引不一定是连续的。如果数组元素分配中存在间隙或某些元素未设置,则索引范围中可能存在间隙。

The script above will output all indexes of the array for which its content is equal to the first command line argument of the script.

上面的脚本将输出数组的所有索引,其内容等于脚本的第一个命令行参数。

EDIT:

编辑:

In your question, you seem to want the result as a one-based array index. In that case you can just increment the result by one:

在您的问题中,您似乎希望结果作为基于 1 的数组索引。在这种情况下,您可以将结果加一:

#!/bin/bash

A=(AA BB CC DD EE)

for i in "${!A[@]}"; do
        if [[ "${A[i]}" = "" ]]; then
                let i++;

                echo "$i"
        fi
done

Keep in mind, though, that this index will have to be decrementedbefore being used with a zero-based array.

但请记住,该索引在与基于零的数组一起使用之前必须递减

回答by dogbane

Loop over the array and keep track of the position. When you find the element matching the input argument, print out the position of the element. You need to add one to the position, because arrays have zero-based indexing.

循环遍历数组并跟踪位置。当找到与输入参数匹配的元素时,打印出该元素的位置。您需要在位置上加 1,因为数组具有从零开始的索引。

#! /bin/sh
arg=
echo $arg
test_array=('AA' 'BB' 'CC' 'DD' 'EE')
element_count=${#test_array[@]}
index=0

while [ $index -lt $element_count ]
do    
  if [ "${test_array[index]}" = "$arg" ]
  then
     echo $((index+1))
     break
  fi
  ((index++))
done

回答by AlexanderKL

Without loop:

无循环:

#!/bin/bash

index() {
    local IFS=$'\n';
    echo "${*:2}" | awk '
5
== "'"${1//\"/\\"}"'" { print NR-1; exit; }' } array=("D A D" "A D" bBb "D WW" D "\" D \"" e1e " D " E1E D AA "" BB) element=${array[5]} index "$element" "${array[@]}"

Output:

输出:

##代码##