将bash数组分成两对,然后在任一元素上进行匹配

时间:2019-01-29 00:16:05

标签: arrays bash

我有一个bash脚本,它像这样一次一次遍历2个数组列表;

#!/bin/bash

declare -a arr=(
    "apple" "fruit"
    "lettuce" "vegetables"
    "almonds" "nuts"
)

for ((i=0; i<${#arr[@]}; i+=2)); do
    echo "${arr[i]} ${arr[i+1]}"
done

当您运行此脚本时,它会打印出来;

apple fruit
lettuce vegetables
almonds nuts

我正在寻找一种从数组中选择特定项目并仅打印该项目的方法,就像这样;

./script.sh apple

,它将仅打印出苹果和带有苹果的第二项;

apple fruit

或者可以是另一种方式,例如; ./script.sh fruit,它将打印出来;

apple fruit

如果没有给出任何参数,只需打印出所有内容即可。

所以我基本上是在寻找一种从阵列中选择项目的方法,这可能与bash阵列有关吗?

2 个答案:

答案 0 :(得分:3)

首先,作为最简单的事情,采用您现有的确切逻辑,并在打印操作周围添加一个条件:

mkdir -p Build && gfortran -O3 -Werror -Wno-unused -fimplicit-none -Wall -fcheck=bound,do -ffpe-trap=invalid,zero,overflow -I/usr/local/include/ -J"./Build" -c "pchip_prb.f90" -o "Build/pchip_prb.o" (in directory: /Users/yajiewang/Desktop/try_new)
pchip.f90:12969:0:
 FUNCTION RAND ( R )
Error: 'rand' declared at (1) is also the name of an intrinsic.  It can only be called via an explicit interface or if declared EXTERNAL. [-Werror=intrinsic-shadow]
pchip.f90:245:13:
      ITRUE = SIGN (ONE, DELTA)
             1
Error: Possible change of value in conversion from REAL(4) to INTEGER(4) at (1) [-Werror=conversion]
pchip.f90:1011:13:
      ITRUE = DSIGN (ONE, DELTA)
             1
Error: Possible change of value in conversion from REAL(8) to INTEGER(4) at (1) [-Werror=conversion]
pchip.f90:13102:8:
   IX1 = MOD(R,1.)*4194304. + 0.5E+00
        1
Error: Possible change of value in conversion from REAL(4) to INTEGER(4) at (1) [-Werror=conversion]
pchip.f90:1813:54:
   CALL DCHFEV (0.D0, 1.D0, 3.D0, 7.D0, 3.D0, 6.D0, 0, DUM, DUM, NEXT, IERR)
                                                      1
Error: Rank mismatch in argument 'xe' at (1) (rank-1 and scalar) [-Werror=argument-mismatch]
pchip.f90:1817:54:
   CALL DCHFEV (1.D0, 1.D0, 3.D0, 7.D0, 3.D0, 6.D0, 1, DUM, DUM, NEXT, IERR)
                                                      1
Error: Rank mismatch in argument 'xe' at (1) (rank-1 and scalar) [-Werror=argument-mismatch]
pchip.f90:1821:54:
   CALL DCHFDV (0.D0, 1.D0, 3.D0, 7.D0, 3.D0, 6.D0, 0, DUM, DUM, DUM, NEXT, IERR)
                                                      1
Error: Rank mismatch in argument 'xe' at (1) (rank-1 and scalar) [-Werror=argument-mismatch]
pchip.f90:1825:54:
   CALL DCHFDV (1.D0, 1.D0, 3.D0, 7.D0, 3.D0, 6.D0, 1, DUM, DUM, DUM, NEXT, IERR)
                                                      1
Error: Rank mismatch in argument 'xe' at (1) (rank-1 and scalar) [-Werror=argument-mismatch]
pchip.f90:1846:39:
   CALL DPCHFE (1, X, F, D, 1, SKIP, 0, DUM, DUM, IERR)
                                       1
Error: Rank mismatch in argument 'xe' at (1) (rank-1 and scalar) [-Werror=argument-mismatch]
pchip.f90:1851:39:
   CALL DPCHFE (N, X, F, D, 1, SKIP, 0, DUM, DUM, IERR)
                                       1
Error: Rank mismatch in argument 'xe' at (1) (rank-1 and scalar) [-Werror=argument-mismatch]
pchip.f90:1856:39:
   CALL DPCHFE (N, X, F, D, 1, SKIP, 0, DUM, DUM, IERR)
                                       1
Error: Rank mismatch in argument 'xe' at (1) (rank-1 and scalar) [-Werror=argument-mismatch]
pchip.f90:1861:39:
   CALL DPCHFD (1, X, F, D, 1, SKIP, 0, DUM, DUM, DUM, IERR)
                                       1
Error: Rank mismatch in argument 'xe' at (1) (rank-1 and scalar) [-Werror=argument-mismatch]
pchip.f90:1866:39:
   CALL DPCHFD (N, X, F, D, 1, SKIP, 0, DUM, DUM, DUM, IERR)
                                       1
Error: Rank mismatch in argument 'xe' at (1) (rank-1 and scalar) [-Werror=argument-mismatch]
pchip.f90:1871:39:
   CALL DPCHFD (N, X, F, D, 1, SKIP, 0, DUM, DUM, DUM, IERR)
                                       1
Error: Rank mismatch in argument 'xe' at (1) (rank-1 and scalar) [-Werror=argument-mismatch]
pchip.f90:7428:53:
   CALL CHFEV (0.E0, 1.E0, 3.E0, 7.E0, 3.E0, 6.E0, 0, DUM, DUM, NEXT, IERR)
                                                     1
Error: Rank mismatch in argument 'xe' at (1) (rank-1 and scalar) [-Werror=argument-mismatch]
pchip.f90:7432:53:
   CALL CHFEV (1.E0, 1.E0, 3.E0, 7.E0, 3.E0, 6.E0, 1, DUM, DUM, NEXT, IERR)
                                                     1
Error: Rank mismatch in argument 'xe' at (1) (rank-1 and scalar) [-Werror=argument-mismatch]
pchip.f90:7436:53:
   CALL CHFDV (0.E0, 1.E0, 3.E0, 7.E0, 3.E0, 6.E0, 0, DUM, DUM, DUM, NEXT, IERR)
                                                     1
Error: Rank mismatch in argument 'xe' at (1) (rank-1 and scalar) [-Werror=argument-mismatch]
pchip.f90:7440:53:
   CALL CHFDV (1.E0, 1.E0, 3.E0, 7.E0, 3.E0, 6.E0, 1, DUM, DUM, DUM, NEXT, IERR)
                                                     1
Error: Rank mismatch in argument 'xe' at (1) (rank-1 and scalar) [-Werror=argument-mismatch]
pchip.f90:7461:42:
       CALL PCHFE (1, X, F, D, 1, SKIP, 0, DUM, DUM, IERR)
                                          1
Error: Rank mismatch in argument 'xe' at (1) (rank-1 and scalar) [-Werror=argument-mismatch]
pchip.f90:7466:42:
       CALL PCHFE (N, X, F, D, 1, SKIP, 0, DUM, DUM, IERR)
                                          1
Error: Rank mismatch in argument 'xe' at (1) (rank-1 and scalar) [-Werror=argument-mismatch]
pchip.f90:7471:42:
       CALL PCHFE (N, X, F, D, 1, SKIP, 0, DUM, DUM, IERR)
                                          1
Error: Rank mismatch in argument 'xe' at (1) (rank-1 and scalar) [-Werror=argument-mismatch]
pchip.f90:7476:42:
       CALL PCHFD (1, X, F, D, 1, SKIP, 0, DUM, DUM, DUM, IERR)
                                          1
Error: Rank mismatch in argument 'xe' at (1) (rank-1 and scalar) [-Werror=argument-mismatch]
pchip.f90:7481:42:
       CALL PCHFD (N, X, F, D, 1, SKIP, 0, DUM, DUM, DUM, IERR)
                                          1
Error: Rank mismatch in argument 'xe' at (1) (rank-1 and scalar) [-Werror=argument-mismatch]
pchip.f90:7486:42:
       CALL PCHFD (N, X, F, D, 1, SKIP, 0, DUM, DUM, DUM, IERR)
                                          1
Error: Rank mismatch in argument 'xe' at (1) (rank-1 and scalar) [-Werror=argument-mismatch]
f951: all warnings being treated as errors
Compilation failed.

但是,如果在您的实际用例中,您将在同一个脚本中进行多次调用,那么值得花费查找表的开销:

#!/bin/bash

declare -a arr=(
    "apple" "fruit"
    "lettuce" "vegetables"
    "almonds" "nuts"
)

for ((i=0; i<${#arr[@]}; i+=2)); do
    if [[ ${arr[i]} = "$1" ]] || [[ ${arr[i+1]} = "$2" ]]; then
        echo "${arr[i]} ${arr[i+1]}"
    fi
done

...之后,您可以便宜地运行:

# initial setup, only needs to happen once
declare -a arr=(
    "apple" "fruit"
    "lettuce" "vegetables"
    "almonds" "nuts"
)
declare -A arrayFwd arrayRev
for ((i=0; i<${#arr[@]}; i+=2)); do
    arrayFwd[${arr[i]}]=${arr[i+1]}
    arrayRev[${arr[i+1]}]=${arr[i]}
done

lookup() {
  if [[ ${arrayFwd[$1]} ]]; then
    echo "$1 ${arrayFwd[$1]}"
  elif [[ ${arrayRev[$1]} ]]; then
    echo "${arrayRev[$1]} $1"
  fi
}

lookup apple

...无论查找表中有多少项,性能都将相同。

答案 1 :(得分:1)

通过添加一个简单的测试来确保(1)不匹配最后一个元素,并且(2)当前元素等于输入参数,您可以输出 current 数组中的下一个元素:

更新为在未提供位置参数的情况下全部输出

#!/bin/bash

declare -a arr=(
    "apple" "fruit"
    "lettuce" "vegetables"
    "almonds" "nuts"
)

declare -i nelem=${#arr[@]}

for ((i = 0; i< nelem; i++)); do
    if [ -z "$1" ]; then    ## no argument given - output all
        echo "${arr[i]}"
    else
        ## test not last element and current equals input
        [ "$i" -lt $((nelem - 1)) ] && [ "${arr[i]}" = "$1" ] &&
        echo "${arr[i]} ${arr[$((i+1))]}"
    fi
done

使用/输出示例

$ bash a.sh apple
apple fruit

$ bash a.sh lettuce
lettuce vegetables

$ bash a.sh almonds
almonds nuts

$ bash a.sh nuts
(no output)

无输入大小写:

$ bash a.sh
apple
fruit
lettuce
vegetables
almonds
nuts

仔细检查一下,如果还有其他问题,请告诉我。