2015-01-29 2 views
1

항목을 나타내는 콜론으로 구분 된 값의 데이터베이스 파일을 저장하는 것이 전제입니다.파일 bash에서 부분 문자열 일치 검색

var1:var2:var3:var4 

이 파일을 정렬하고 값이 검색 문자열과 일치하는 줄을 추출해야합니다. 예

Search for "Help" 
Hey:There:You:Friends 
I:Kinda:Need:Help (this line would be extracted) 

들어 는 I 출력 형식을 다른 기능으로 발견 라인을 통과 한 후, 검색 문자열을 전달하는 기능을 사용하고있어. 그러나 나는 통과 할 때 바로 형식을 얻을 수있을 것 같지 않습니다. 여기에 내가이 사이트에서 발견 한 여러 가지 방법으로 시도했습니다 샘플 코드는,하지만 그들은 내가 찾을 수있는 최초의 하나를 얻을 수없는 것

#Option 1, it doesn't ever find matches 
function retrieveMatch { 
    if [ -n "$1" ]; then 
    while read line; do 
     if [[ *"$1"* =~ "$line" ]]; then 
     formatPrint "$line" 
     fi 
    done 
    fi 
} 

#Option 2, it gets all the matches, but then passes the value in a 
#format different than a file? At least it seems to... 
function retrieveMatch { 
    if [ -n "$1" ]; then 
    formatPrint `cat database.txt | grep "$1"` 
    fi 
} 

function formatPrint { 
    list="database.txt" #default file for printing all info 
    if [ -n "$1" ]; then 
    list="$1" 
    fi 
    IFS=':' 
    while read var1 var2 var3 var4; do 
    echo "$var1" 
    echo "$var2" 
    echo "$var3" 
    echo "$var4" 
    done < "$list" 
} 

나를 위해 작동하지 않는 것 모든 일치 두 번째 옵션은 올바른 값을 가져 오지만 formatPrint를 시도하면 전달 된 값 목록이 디렉토리가 아니라는 오류가 발생합니다.

+0

나는 "$ line"= ~ * "$ 1"*'행운을 빈다고 생각한다. – shellter

+0

포인트 세부 정보 (& 간결)를 제공해야합니다. 당신이 필요로하는 것이 무엇인지 알아내는 것은 어려울 것입니다. – Aman

+0

(1) 일치하는 항목이 전체 필드 또는 부분 필드에 있어야합니까? 다시 말해, 'Hey : There : You : Friends I : Kinda : Need : Help' 문자열에 대해'He '라는 문자열이 일치해야합니까? (2) 원하는 샘플 출력을 보여주십시오? 샘플 코드는 각 필드를 별도의 줄에 넣으려고합니다. 너가 원하는게 그거야? – John1024

답변

2

솔직히 [-D 제어를 제공]

cat > foo.bsh 
#!/bin/bash 
hits="$(grep -i help foo.txt)" 
while read -r line; do 
    echo "${line}" 
done <<< "$hits" 

이 ..이 생각에 조금 더를 확장

function retrieveMatch { 
    grep "$1" | tr ':' '\n' 
} 

로 부름

retrieveMatch Help < filename 

... 원래 기능 (옵션 1)처럼 설계된 것으로 보입니다. 더 복잡한 작업을 수행하려면 awk를 살펴보십시오.

# in the awk script, the fields in the line will be $1, $2 etc. 
awk -v pattern="$1" -F : '$0 ~ pattern { for(i = 1; i < NF; ++i) print $i }' 

this link을 참조하십시오. Awk는 이러한 종류의 데이터를 정확하게 처리하도록 만들어 졌으므로 복잡한 작업을 계획한다면 분명히 가치가 있습니다.

질문에 더 직접적인 대답을하면 코드에 2/3 문제가 있습니다. 질문에 대한 의견에서 지적 된 바와 같이 하나는 라인

if [[ *"$1"* =~ "$line" ]]; then 

*"$1"* 하나 개 이상의 토큰이되지 않는 것으로 가정 *"$1"*에서 일치를 찾는 정규 표현식으로 "$line"를 사용하려고 것,입니다 경로 이름 확장 후 *이 인용되지 않기 때문에 정규식의 어떤 부분 일치하는 경우 =~이 경기를보고 있기 때문에 *이 (정규 표현식에하지만) 아무것도에게 그들이 글로브 표현에서와 방법에 맞게 해야하는 가정하면, 이것은

if [[ "$line" =~ "$1" ]]; then 

로 대체 할 수있다 끈.

두 번째 문제는 "$list" (formatPrint)이 파일인지 한 줄인지를 구분하는 것입니다. 당신은 선해야한다고 retrieveMatch의 말 :

formatPrint "$line" 

하지만 당신은 formatPrint에 파일 이름 기본으로 설정 :

list="database.txt" #default file for printing all info 

당신은 하나를 결정해야합니다. 당신이 formatPrint 선을 포맷해야한다고 결정하는 경우, 세 번째 문제는

while read var1 var2 var3 var4; do 
    echo "$var1" 
    echo "$var2" 
    echo "$var3" 
    echo "$var4" 
done < "$list" 

의 리디렉션을 파일 이름으로 "$list"을 사용하려고한다는 것입니다. 이

done <<< "$list" # using a here-string (bash-specific) 

또는

done <<EOF 
$list 
EOF 

과 마지막 줄을 교체함으로써 해결 될 수있다 (참고 : 후자의 경우, 코드 들여 쓰기를하지 않습니다, 그것은 그대로 촬영하고 여기-문서의). 물론, read은 4 개의 필드를 작성한 방식으로 분할합니다.

+0

당신은 파일/라인 딜레마, cat | grep은 실제로 파일을 생성하지 않으므로 $ list를 파일이 아닌 파일의 출력으로 덮어 쓰려고 시도하면 오류가 발생합니다. 모두 좋다! – errorline1

1

나는

cat > foo.txt 
Hey:There:You:Friends I:Kinda:Need:Help 
Foo:Bar 

grep -i help foo.txt 
Hey:There:You:Friends I:Kinda:Need:Help 

이 법안에 적합합니까 [CONTROL-D주세요] 내가 모르는 뭔가가 있어야합니다 느끼지만, ..?

편집 : 내가 가진 모든 것을 바꿀 것,