CSV 파일에서 값을 검색한 다음 이와 관련된 다른 값을 가져오는 방법은 무엇입니까?

CSV 파일에서 값을 검색한 다음 이와 관련된 다른 값을 가져오는 방법은 무엇입니까?

myfile.csv

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를 사용하는 더 쉬운 방법이 있는지 잘 모르겠습니다.

답변1

이 시도:

 awk -F',' '{ if ($2 == "anotherLabel") { print $1 } }' myfile.csv

답변2

사용 greptail:

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일치하는 부품(번호)만 인쇄됩니다.

답변3

순수 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"

답변4

다음 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

관련 정보