bash - 如何正确读取值在数组中的输入文件

时间:2017-08-30 13:57:27

标签: bash shell unix

我试图编写一个读取文件的脚本(多行) 这是"#"分开并将它们放在一个数组中,这样我就可以匹配一些值。

示例输入文件:

us-east#1-1#abcdefg1234Ad
us-west#1-3#654kjhytgr
us-east#1-4#lkjhg765

我尝试做的是读取每一行 并根据我的输入参数($ 1)给我匹配。 我只是坚持只评估第一行。

这是我的代码:(执行: ./ myscript.sh us-east-1-3

#!/usr/local/bin/bash
set -x
cluster=$1

KEY=./.keyfile

while IFS=#
declare -a arr=($(< $KEY)); do
if [[ ${arr[0]}-${arr[1]} == $1 ]]; then
    echo "We have a match"
 else
    echo "No match"
    exit 1
fi
done

set +x

2 个答案:

答案 0 :(得分:2)

  

我只是在评估第一行时被困住了。

因为在else块中你有exit语句,假设如果行不匹配,则循环将因exit 1而终止,因此不会进行进一步的迭代。

在阅读第一行后,us-east-1-1不等于us-east-1-3,布尔false,因此在else块中您有exit语句,因此终止

+ cluster=us-east-1-3
+ KEY=./file
+ IFS='#'
+ arr=($(< $KEY))
+ declare -a arr
+ [[ us-east-1-1 == us-east-1-3 ]]
+ echo 'No match'                  
No match
+ exit 1

您可以进行如下修改,以便您使用更少的资源,逐行阅读而不是将整个文件读入数组

[akshay@localhost tmp]$ cat t.sh
#!/usr/bin/env bash

set -x
cluster="$1"

while IFS=# read -r  field1 field2 restother; do
if [[ "$field1-$field2" == $1 ]]; then
    echo "We have a match"
 else
    echo "No match"
fi
done < "file"

set +x

输出when cluster=us-east-1-3

[akshay@localhost tmp]$ bash t.sh us-east-1-3
+ cluster=us-east-1-3
+ IFS='#'
+ read -r field1 field2 restother
+ [[ us-east-1-1 == us-east-1-3 ]]
+ echo 'No match'
No match
+ IFS='#'
+ read -r field1 field2 restother
+ [[ us-west-1-3 == us-east-1-3 ]]
+ echo 'No match'
No match
+ IFS='#'
+ read -r field1 field2 restother
+ [[ us-east-1-4 == us-east-1-3 ]]
+ echo 'No match'
No match
+ IFS='#'
+ read -r field1 field2 restother
+ set +x

输出when cluster=us-west-1-3

[akshay@localhost tmp]$ bash t.sh us-west-1-3
+ cluster=us-west-1-3
+ IFS='#'
+ read -r field1 field2 restother
+ [[ us-east-1-1 == us-west-1-3 ]]
+ echo 'No match'
No match
+ IFS='#'
+ read -r field1 field2 restother
+ [[ us-west-1-3 == us-west-1-3 ]]
+ echo 'We have a match'
We have a match
+ IFS='#'
+ read -r field1 field2 restother
+ [[ us-east-1-4 == us-west-1-3 ]]
+ echo 'No match'
No match
+ IFS='#'
+ read -r field1 field2 restother
+ set +x

您可以将awk用于此类目的,也可以更快地使用

以下是一些示例

$ cat file 
us-east#1-1#abcdefg1234Ad
us-west#1-3#654kjhytgr
us-east#1-4#lkjhg765

输出(cluster="us-east-1-3"时)

$ awk -F'#' -v cluster="us-east-1-3"  '{ print (cluster==$1"-"$2)? "We have a match": "No match"}' file
No match
No match
No match

输出(cluster="us-west-1-3"时)

$ awk -F'#' -v cluster="us-west-1-3"  '{ print (cluster==$1"-"$2)? "We have a match": "No match"}' file
No match
We have a match
No match

答案 1 :(得分:1)

我同意Akshay的观点,这是用awk解决的一个很好的问题。但是,如果你真的想单独使用shell,那就不难了:

#!/usr/bin/env bash

cluster="$1"
keyfile=keyfile.txt

ret=0
while IFS='#' read -r one two three; do
  if [[ "${one}-${two}" = "$cluster" ]]; then
    echo "match"
  else
    echo "no match"
    ret=1
  fi
done < "$keyfile"

exit $ret

关键区别在于,这是使用read来处理传递给while循环的输入流,而不是为每次运行重新评估$(< $keyfile)表达式循环(我希望每次运行都会给你第一行)。