445,aLabel
446,anotherLabel
447,aThirdLabel
Bashスクリプトで、myfile.csv内で(大文字と小文字を区別しない方法で)「anotherLabel」の存在を検索し、値446を取得します。さらに、「anotherLabel」が存在しない場合は追加します最後まで、前の行のトークンを1増やします。
if
ステートメントから始めました:
if grep -Fiq anotherLabel myfile.csv; then
#get the value of field 1 (446 in this example) and store it in a variable
else
#increment the last value of field 1 present in the file and store it in a variable
#and append "448,anotherLabel" to myfile.csv
fi
Grepを使用してラベルがファイル内にあるかどうかを確認することがこれに近づく最善の方法であるか、sedまたはawkを使用するより簡単な方法があるかどうかはわかりません。
これはあなたが必要とするものです:
$ 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
上記は、$ 2に一致するか、ファイルの最後にstderrに新しく追加された$ 1を出力し(変数「var」にキャプチャされます)、ターゲット文字列が見つかった場合は終了ステータスを成功に設定し、それ以外の場合は失敗に設定します、ファイル全体をstdoutに出力し、必要に応じて欠損値を追加します。
これを試してください:
awk -F',' '{ if ($2 == "anotherLabel") { print $1 } }' myfile.csv
次の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
に変更して、より緩やかに一致させる)、それが見つかったインデックスを報告します。文字列が一致しない場合、ファイルの最後のインデックスより1つ多いインデックスで使用されるファイルに追加(追加)されます。
例:
_$ ./script aLabel
445
$ ./script anotherLabel
446
$ ./script MissingLabel
450
$ cat myfile.csv
445,aLabel
446,anotherLabel
447,aThirdLabel
448,dhdhdhdhdhd
449,anotherLabel4646
450,MissingLabel
_
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
_と組み合わせて、一致する部分(数値)のみが出力されます。
純粋なbashでこれを実行したい場合:
file="myfile.csv"
seek="anotherLabel"
while IFS=, read id label; do
if [[ $label == "$seek" ]]; then
myid=$id
break
fi
lastid=$id
done < "$file"
if [[ -z $myid ]]; then
myid=$((lastid + 1))
echo "$myid,$seek" >> "$file"
fi
echo "$seek id is: $myid"
診断とエラー処理を省略した場合は、これを少し短くすることができます。
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
これは Bart’s answer に基づいており、awk
を使用して各行の2番目のフィールド($2
)を目的のラベルと比較しますが、テストでは大文字と小文字を区別しません。上記のコードの実行後、$var1
には、$label
に対応する値が含まれます。 $var2
が空白でない場合は、見つかったexactラベルが含まれています。 $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