数字が他の数字に「含まれる」出力問題について

数字が他の数字に「含まれる」出力問題について

これは私のスクリプトです。add_nurses.sh:

#!/bin/bash

sed -i '/^$/d' nurses.txt

if [ $# != 4 ] ; then
    echo "Error: Syntax: $0 <id number>:<name>:<associated Health Center>:<number of vaccines done>:<availabiliy>"
else

a=$(awk -F "[:]" '{print $3}' nurses.txt | grep -c "$3")
b=$(awk -F "[:]" '{print $1}' nurses.txt | grep -c "$2")

if [[ "$a" -gt "0" ]] ; then
    echo "Error: The Health Center introduced already has a nurse in it."

    elif [[ "$b" -gt "0" ]] ; then
        echo "Error: There is already a nurse registered with that id."

    else
    
    echo "$2:$1:$3:0:$4" >> nurses.txt
    echo "Nurse added."
    fi
fi

このスクリプトを使ってナースXをnurses.txtに追加したいと思います。ただし、Xと同じ場所にすでに登録されている看護師がいる場合、またはXが所有するIDをnurse.txtの他の看護師がすでに使用している場合は、X看護師をリストに追加したくありません。

私のもの看護師.txt内容は次のとおりです。

12345:Ana Correia:CSLisboa:0:0
98765:Joao Vieira:CSPorto:0:1

次のようにプログラムを実行すると:

./add_nurses.sh "João Vieira" 98765 "CSPorto" 0

このパラメータについて私が受け取る正しいメッセージは次のとおりです。

Error: The Health Center introduced already has a nurse in it.

CSPortoたとえば、文字数は同じですが、文字数が異なる文字列に位置を変更した場合は、次のようになります。

./add_nurses.sh "João Vieira" 98765 "CSPorta" 0

また、次の正しい出力を取得します。

Error: There is already a nurse registered with that id.

しかし、次のように入力すると:

./add_nurses.sh "João Vieira" 9876 "CSPorta" 0

それは私に間違った出力を与えます。つまり:

Error: There is already a nurse registered with that id.

id98765とは9876異なります。では、この出力が表示されるのはなぜですか。この問題を解決する方法は?

返品、以下のように少ない文字で保健所に入ると:

./adiciona_enfermeiros.sh "João Vieira" 98765 "CSPort" 0

私は得る:

Error: The Health Center introduced already has a nurse in it.

CSPortしかし、スクリプトが両方の問題について助けを必要としないか、同じ場所を想定したいと思います!よろしくお願いします:)CSPortoCSPorta

ベストアンサー1

すでに述べたように、問題はあなたの方法が部分文字列も見つけることです。ただし、ファイルを複数回読み込み、grepそれを使用して行のどこにでも一致するものを見つけるため、すべてが非常に不安定で非効率的です。代わりに、awk1回の呼び出しで完全な処理を行います。このような:

#!/bin/bash

if [ $# != 4 ] ; then
    echo "Error: Syntax: $0 <id number> <name> <associated Health Center> <number of vaccines done> <availabiliy>"
    exit 1
fi

## Have awk print out 'var=value' pairs and 'source' them
## into your current shell so they will be available as
## variables in the current script.
. <(awk -v id="$2" -v center="$3" -F':' \
        '{
           if($1==id){i=1}
           if($3==center){c=1}
         } END{ print "idExists="i,"centerHasNurse="c}' nurses.txt)


## I am separating the two tests since they are not mutually exclusive
## this way, you will get separate messages when the id exists and when
## the nurse exists. Either error will cause the script to fail, but this
## way you will know if the id exists and the center has a nurse.
foundError=""
if [[ -n $idExists ]]; then
  echo "Error: There is already a nurse registered with that id."
  foundError=1 
fi

if [[  -n $centerHasNurse ]]; then
  echo "Error: The Health Center introduced already has a nurse in it."
  foundError=1
fi

if [[ -n $foundError ]]; then
  exit 1
fi

## If we got to this part, there were no errors and we can modify the file
echo "$2:$1:$3:0:$4" >> nurses.txt
echo "Nurse added."

おすすめ記事