Это делает 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
Я считаю, что проблема в том, что grep 9876
видит, что 9876
присутствует, но вы хотите видеть его, только если число присутствует как слово. Если вы используете переключатель -w
при поиске идентификационного номера, вы должны получить ответ, который ищете. По той же причине он видит CSport
присутствующим либо в CSporto
, либо в CSporta
. Переключение -w
на grep также должно решить эту проблему.
a=$(awk -F "[:]" '{print $3}' nurses.txt | grep -cw "$3")
Как уже упоминалось, проблема в том, что ваш подход также будет находить подстроки. Однако все это довольно хрупко и неэффективно, поскольку вы читаете файл несколько раз и используете 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."
Как указывали другие, grep -c "$3"
и grep -c "$2"
выполняют поиск по регулярному выражению, который по умолчанию (в grep
, по крайней мере ), не является полным совпадением (, т.е. от начала до конца )между строкой и шаблоном. Кроме того, поиск по регулярному выражению вместо проверки на равенство может привести к нежелательным результатам, когда шаблоны("$3"
и "$2"
, в вашем случае ), могут включать специальные символы (, например. CSPorto01
будет соответствовать шаблону CSPorto.1
).
Помимо предложения решения этой проблемы, вот пример того, как вы можете получить больше преимуществ от функций AWK. Ваша программа разделена на сценарий оболочки add_nurses.sh
и сценарий add_nurses.awk
AWK.
#!/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
's add_nurses.sh
)[[... ]]
заменяется на [... ]
; по той же причине я использовал#!/bin/sh