Следующий awk-код делает то, что вы просите:
#!/bin/bash
filetosearch=myfile.csv
searchString=${1:-anotherLabel}
awk -F',' -v pat="$searchString" '
BEGIN{patl=tolower(pat);flag=0};
{prev=$1}(tolower($0)==patl){flag=1;exit}
END{
if(flag){
print prev
}else{
printf("%s%s%s\n", prev+1,FS,pat) >> ARGV[1] # use ARGIND in gawk.
print prev+1
}
}' "${filetosearch}"
Поиск строки "${searchString}"
, которая точно соответствует полной строке (изменение tolower($0)==patl
на tolower($0)~patl
для более слабого соответствия )и сообщает, по какому индексу она была найдена. Если строка не соответствует, она добавляется (в конце )к используемому файлу с индексом, который на единицу больше, чем последний индекс файла.
Пример:
$./script aLabel
445
$./script anotherLabel
446
$./script MissingLabel
450
$ cat myfile.csv
445,aLabel
446,anotherLabel
447,aThirdLabel
448,dhdhdhdhdhd
449,anotherLabel4646
450,MissingLabel
Это то, что вам нужно:
$ awk -v tgt='the string you want to find' '
BEGIN { FS=OFS="," }
tolower($2) == tolower(tgt) { print $1 | "cat>&2"; f=1 }
{ print; p=$1 }
END { if (!f) { print ++p, tgt; print p | "cat>&2"} exit !f }
' file
Например:
$ var=$( { awk -v tgt='anotherLabel' 'BEGIN{FS=OFS=","} tolower($2) == tolower(tgt){print $1 | "cat>&2"; f=1} {print; p=$1} END {if (!f) { print ++p, tgt; print p | "cat>&2"} exit !f}' file > out1; } 2>&1 )
$ echo "exit status: $?, value found: $var"
exit status: 0, value found: 446
$ cat out1
445,aLabel
446,anotherLabel
447,aThirdLabel
$ var=$( { awk -v tgt='missingLabel' 'BEGIN{FS=OFS=","} tolower($2) == tolower(tgt){print $1 | "cat>&2"; f=1} {print; p=$1} END {if (!f) { print ++p, tgt; print p | "cat>&2"} exit !f}' file > out1; } 2>&1 )
$ echo "exit status: $?, value found: $var"
exit status: 1, value found: 448
$ cat out1
445,aLabel
446,anotherLabel
447,aThirdLabel
448,missingLabel
В приведенном выше примере любой $1, совпадающий с $2 или вновь добавленный в конец файла, будет напечатан в stderr (, который затем фиксируется в переменной, «var» )устанавливает статус выхода как успех, если целевая строка была найдена, в противном случае произойдет сбой, и выведите весь файл на стандартный вывод с добавлением отсутствующего значения, если это необходимо.
Попробуйте:
awk -F',' '{ if ($2 == "anotherLabel") { print $1 } }' myfile.csv
Использование grep
иtail
:
search="anotherLabel"
file=myfile.csv
if value=$(grep -Pio -m1 "^[0-9]+(?=,$search$)" "$file"); then
echo "do something with $value"
elif lastvalue=$(tail -n1 "$file" | grep -o '^[0-9]\+'); then
# append lastvalue + 1 and search string
echo "$((++lastvalue)),$search" >> "$file"
else
# handle error
echo "error. no integer value in last line of \"$file\" found." >&2
fi
В первом grep
используются следующие опции:
-P
включить Perl -совместимое регулярное выражение (PCRE )для использования положительного просмотра вперед (см. ниже ). -i
игнорировать регистр в шаблоне -o
вывести только совпадающую часть строки -m1
остановить после первого совпадения Первое регулярное выражение ^[0-9]+(?=,$search$)
использует положительный просмотр вперед (?=pattern)
для сопоставления числа, за которым следует ,
и строки поиска без запятой, а строка поиска является частью самого совпадения. В сочетании с опцией -o
печатается только совпадающая часть (с номером ).
Вы могли бы сделать это немного короче если вы сняли диагностику и обработку ошибок -:
file="myfile.csv"
label="$1"
if [ "$label" != "" ]
then
IFS="," read val1 val2 <<< "$(awk -F, -v look4="$label" \
'tolower($2) == tolower(look4) { found=1; print $1 "," $2; }
END { if (!found) print $1; }' "$file")"
if [ "$val2" != "" ]
then
echo "Found value $val1 with label $val2."
else
val1=$((val1+1))
if printf "%s,%s\n" "$val1" "$label" >> "$file"
then
echo "Added value $val1 to file for label $label."
else
echo "Failed to add value $val1 to file."
fi
fi
else
echo "Missing label."
exit
fi
Это основано на ответе Барта , используя awk
для сравнения второго поля($2
)в каждой строке к желаемой метке, но делает тестовый пример -нечувствительным. После запуска приведенного выше кода $var1
будет содержать значение, соответствующее $label
, так или другой. Если $var2
не пусто, то оно содержит найденную метку точно . Если $var2
пусто, ярлык не найден (и была предпринята попытка добавить его в файл ).
Я сделал с приведенным ниже скриптом
Дайте мне знать, если есть какие-либо данные
count=`awk '{print NR}' o.txt| awk '{print NR}'|sed -n '$p'`
for ((i=1;i<=$count;i++)); do sed -n ''$i'p' o.txt| grep "anotherLabel">/dev/null; if [[ $? == 0 ]]; then echo "anotherlabel exists"; awk -F "," -v i="$i" 'NR==i && $2 == "anotherLabel" {print $1}' o.txt; uni_anotherlabel=`sed -n ''$i'p' o.txt| grep "anotherLabel"| awk -F "," '{print $1}'`;else echo "anotherlabel doesnt exsists"; echo "$uni_anotherlabel"; fi; done