grep은 마침표가 포함된 정확한 단어 일치를 찾습니다.

grep은 마침표가 포함된 정확한 단어 일치를 찾습니다.

.csv다음 형식의 대용량 파일이 있습니다.

"acc","lineage"
"MT993865","B.1.509"
"MW483477","B.1.402"
"MW517757","B.1.2"
"MW517758","B.1.2"
"MW592770","B.1.564"
...

accession_id즉, 첫 번째 열은 데이터 샘플을 나타내는 문자열이고, 두 번째 열은 covid 변종입니다 lineage. 나는 accession_ids와 그 계보를 추출하여 관심 있는 특정 변형, OmicronB.1.1.529. 파일을 찾기 위해 greping을 시도했지만 -w단어 .가 아닌 문자로 인해 확장된 omicron 변형에 대한 결과를 얻었습니다. 예를 들어,B.1.1.529.1

~을 위한상세한토론을 위해 제가 작성한 다음 bash 스크립트를 살펴보십시오.

# filter data based on the selected lineages (refer to variants_lineage.txt for more info) as given below.

# File with metadata
metadata_file="$HOME/thesis/SARS-CoV2-data/metadata.csv"
cat "$metadata_file" | tr -d '"' | tr ',' $'\t' > adj_metadata.tsv

# list of lineages of interest
selected_lineages=("B.1.1.7" "B.1.351" "P.1" "B.1.617.2" "B.1.1.5290" "C.37" "B.1.621" "B.1.429" "B.1.427" "CAL.20C" "P.2" "B.1.525" "P.3" "B.1.526" "B.1.617.1" )
pattern=$(echo ${selected_lineages[*]}|tr ' ' '|')

if [ -f "adj_metadata.tsv" ]
then
  echo "File exists"
  for lineage in ${selected_lineages[@]}
    do
      echo "Filtering for lineage $lineage"
      grep -w "$lineage" adj_metadata.tsv >> filtered_metadata.tsv
    done
else
  echo "Adjusted metadata file does not exist."
fi

# Check for the uniqueness of the filtered_metadata.csv file, this should fetch the list of selected_lineages
cut -d$'\t' -f2 filtered_metadata.tsv | sort | uniq

어떤 제안이나 의견이라도 대단히 감사하겠습니다.

또한, 질문과 관련 없는 개선 사항에 대해 자유롭게 의견을 제시해 주십시오.

미리 감사드립니다.

답변1

방법 1

.csv의 문자열은 항상 큰따옴표 사이에 있으므로 "일치 항목에 따옴표를 포함할 수 있습니다. 그런 다음 '표현식에 작은따옴표를 사용하면 됩니다 .

예:

asdf.csv:

"foo","B.1.1.529"
"bar","B.1.1.529.1"
╰─$ grep  '"B.1.1.529"' ./asdf
"foo","B.1.1.529"

보시다시피 B.1.1.529.1이 경우에는 일치하는 항목이 없습니다.


방법 2

방법 1은 입력 데이터에 작동하지만 adj_metadata.tsv모든 따옴표를 제거하므로 . 물론 먼저 일치하도록 스크립트를 수정한 다음 출력을 파이프할 수 있지만 tr여기에는 불필요한 작업이 포함됩니다.

당신이 할 수 있는 일은 정규식을 줄 끝에 고정하는 것입니다.$

예:

adj-metadata.tsv:

foo     B.1.1.529
bar     B.1.1.529.1
╰─$ grep "B.1.1.529$" adj_metadata.tsv
foo     B.1.1.529

이 방법을 사용하면 스크립트를 수정해야 할 유일한 수정 사항은 \$grep 명령의 올바른 위치에 추가하는 것입니다.

#!/bin/bash
# filter data based on the selected lineages (refer to variants_lineage.txt for more info) as given below.

# File with metadata
metadata_file="$HOME/thesis/SARS-CoV2-data/metadata.csv"
cat "$metadata_file" | tr -d '"' | tr ',' $'\t' > adj_metadata.tsv

# list of lineages of interest
selected_lineages=("B.1.1.7" "B.1.351" "P.1" "B.1.617.2" "B.1.1.5290" "C.37" "B.1.621" "B.1.429" "B.1.427" "CAL.20C" "P.2" "B.1.525" "P.3" "B.1.526" "B.1.617.1" )

#replace all occurrences of "." with "\."
selected_lineages=$(echo $selected_lineages | sed 's/\./\\./g')

if [ -f "adj_metadata.tsv" ]
then
  echo "File exists"
  for lineage in ${selected_lineages[@]}
    do
      echo "Filtering for lineage $lineage"
      grep -w "$lineage\$" adj_metadata.tsv >> filtered_metadata.tsv
    done
else
  echo "Adjusted metadata file does not exist."
fi

# Check for the uniqueness of the filtered_metadata.csv file, this should fetch the list of selected_lineages
cut -d$'\t' -f2 filtered_metadata.tsv | sort | uniq

참고: 일반적으로 모든 문자에 대한 표현식으로 사용되지만 리터럴을 검색하려면 다음과 같이 .a로 이스케이프해야 합니다 .\.B\.1\.1\.529$

\입력하는 동안 단순화를 위해 사용하지 않은 채로 둘 수 있습니다.

관련 정보