Проблема вывода, связанная с тем, что номер уже содержится в другом

Это делает search for the identifying number preceeded by a string that has neither commas nor equal signs [in other words, their name] followed by and equal and replace all with nothing.

sed -r 's/[^,=]+=23456(,|$)//' new.txt
sam=12345,john=98765,bruce=67890,jack=54321,noah=67894,vision=65432,thor=98768,tony=89769,cap=90878
2
13.03.2021, 18:26
3 ответа

Я считаю, что проблема в том, что grep 9876видит, что 9876присутствует, но вы хотите видеть его, только если число присутствует как слово. Если вы используете переключатель -wпри поиске идентификационного номера, вы должны получить ответ, который ищете. По той же причине он видит CSportприсутствующим либо в CSporto, либо в CSporta. Переключение -wна grep также должно решить эту проблему.

a=$(awk -F "[:]" '{print $3}' nurses.txt | grep -cw "$3")
1
18.03.2021, 22:25

Как уже упоминалось, проблема в том, что ваш подход также будет находить подстроки. Однако все это довольно хрупко и неэффективно, поскольку вы читаете файл несколько раз и используете grep, который может найти совпадение в любом месте строки. Вместо этого я бы сделал всю обработку одним вызовом awk. Что-то вроде этого:

#!/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."

2
18.03.2021, 22:25

Как указывали другие, grep -c "$3"и grep -c "$2"выполняют поиск по регулярному выражению, который по умолчанию (в grep, по крайней мере ), не является полным совпадением (, т.е. от начала до конца )между строкой и шаблоном. Кроме того, поиск по регулярному выражению вместо проверки на равенство может привести к нежелательным результатам, когда шаблоны("$3"и "$2", в вашем случае ), могут включать специальные символы (, например. CSPorto01будет соответствовать шаблону CSPorto.1).

Помимо предложения решения этой проблемы, вот пример того, как вы можете получить больше преимуществ от функций AWK. Ваша программа разделена на сценарий оболочки add_nurses.shи сценарий add_nurses.awkAWK.

#!/bin/sh

if [ $# -ne 4 ]
then
  printf '%s\n' "Error: Syntax: $0 <id number>:<name>:<associated Health Center>:<number of vaccines done>:<availabiliy>"
  exit 1
fi

awk -v FS=':' -v OFS=':' -v name="$1" -v id="$2" -v center="$3" -v av="$4" \
  -f add_nurses.awk nurses.txt
#!/bin/awk

$3 == center {
  print "Error: The Health Center introduced already has a nurse in it."
  err++
}
$1 == id {
  print "Error: There is already a nurse registered with that id."
  err++
}
END {
  if (! err) {
    print id,name,center,"0",av >>FILENAME
    print "Nurse added."
  }
}

(Я не буду удалять пустые строки изnurses.txt).

Примечания:

  • Отдельный сценарий AWK легче читать и поддерживать (, но это, вероятно, вопрос личных предпочтений)
  • Вам не нужно регулярное выражение([:])в качестве разделителя полей awk's
  • Имеет смысл вывести все ошибки, которые выдаст ввод, вместо того, чтобы останавливаться после первой
  • ...но, в то же время, нет смысла разбирать входные данные, когда они явно искажены (отсюда и проверка количества аргументов вadd_nurses.sh)
  • Нет реальной необходимости в нестандартных -функциях оболочки, в этом случае:[[... ]]заменяется на [... ]; по той же причине я использовал#!/bin/sh
3
18.03.2021, 22:25

Теги

Похожие вопросы