BASH SHELL:搜索功能未给出正确的结果

时间:2018-01-30 09:38:05

标签: bash shell search grep

据说这是我的数据:

Lord of The Ring:Johnny Dept:56.80:100:38
Three Little Pig:Andrew Lim:89.10:290:189
All About Ubuntu:Ubuntu Team:76.00:55:133
Catch Me If You Can:Mary Ann:23.60:6:2
Happy Day:Mary Ann:12.99:197:101
Harry Potter:J.K Rowling:23:32:421
jo:jojo:2000:120:293

代码:

function search_book
{
    echo "4) search_book"
    read -p "Title: " title
    read -p "Author: " author

    searchtitle=` grep -i "^$title:$author:*" BooksDB.txt | cut -d: -f 1 `
    searchauthor=` grep -i "^$title:$author:*" BooksDB.txt | cut -d: -f 2 `
    #Data does not compute to true if two variables are filled and exist if not typed fully
    if [[ $searchtitle == $title ]] || [[ $searchauthor == $author ]]
    then
    recordcount=`cat | grep -iE "*$title" BooksDB.txt | grep -iEc "$author" `
    echo "Found $recordcount records"
    echo 
    grep -iE "*$title" BooksDB.txt | grep -iE "$author" |\
        awk -F: 'BEGIN{print "Title:Author:Price:Available Copies:Sold Copies\n"}
        {print $1":"$2":$"$3":"$4":"$5}' | column -s ":" -t
    echo 
    else
    echo "No Books found."
    fi

}

节目的输出:

4) search_book
Title: jo
Author: 

Found 2 records

Title             Author       Price   Available Copies  Sold Copies
Lord of The Ring  Johnny Dept  $56.80  100               38
jo                jojo         $2000   120               293

当我的标题是jo时,只有第二条记录应该是结果,但它在哪里以及为什么它会使它同时搜索标题和作者?

预期结果:

4) search_book
Title: jo
Author: 

Found 2 records

Title             Author       Price   Available Copies  Sold Copies
jo                jojo         $2000   120               293

6 个答案:

答案 0 :(得分:1)

只需使用awk,这应该让你开始:

awk -F: -v title="$title" author="$author" \
    'BEGIN { print "Title:Author:Price:Available Copies:Sold Copies\n" }
     $1 ~ $title && $2 ~ $author' BooksDB.txt OFS=:

答案 1 :(得分:0)

你实现搜索的方式,做到正确有点棘手。尝试:

function search_book
{
    echo "4) search_book"
    read -p "Title: " title
    read -p "Author: " author

    searchtitle=` grep -i "^$title" BooksDB.txt | cut -d: -f 1 `
    searchauthor=` grep -i "^[^:]+:$author" BooksDB.txt | cut -d: -f 2 `
    #Data does not compute to true if two variables are filled and exist if not typed fully
    if [[ $searchtitle == $title ]] || [[ $searchauthor == $author ]]
    then
    recordcount=`grep -iE "^$title" BooksDB.txt | grep -iEc "^[^:]+:$author" `
    echo "Found $recordcount records"
    echo
    grep -iE "^$title" BooksDB.txt | grep -iE "^[^:]+:$author" |\
        awk -F: 'BEGIN{print "Title:Author:Price:Available Copies:Sold Copies\n"}
        {print $1":"$2":$"$3":"$4":"$5}' | column -s ":" -t
    echo
    else
    echo "No Books found."
    fi
}

然后,如果你跑:

4) search_book
Title: jo
Author: .*

Found 1 records

Title  Author  Price  Available Copies  Sold Copies
jo     jojo    $2000  120               293

您的搜索模式太宽泛了。最初的几乎是正确的,但其他人不确保在正确的地方匹配正确的字段。例如,对于第二个字段:

^[^:]+:$author

首先会跳过一个字段,从该行的开头搜索除:之外的任何内容,然后搜索:,然后搜索$author变量。如果您想允许空标题,请改用[^:]*

此外,您不能说明您是要实施and还是or。我离开它的方式是and,字段需要从头开始匹配,但不是一直(似乎是你想要的。)

如果您希望空搜索字段与任何内容匹配,您可以在阅读输入后添加条件以将空字段转换为.*

答案 2 :(得分:0)

以下是我将如何实施搜索。显然,只有当用户输入标题等时才会对标题进行搜索。

搜索标题

sed -n -E '/^.*jo.*(:.*){4}$/Ip' file

搜寻作者

sed -n -E '/^.*:.*jo.*(:.*){3}$/Ip' file

这会尝试匹配每一行上的模式(不区分大小写)并在找到模式时打印该行。

答案 3 :(得分:0)

awk是你的朋友。用类似的术语做点什么。

$ awk -v t="$title" -v a="$author" -v FS=":" '
BEGIN{count=0;printf "Title:Author:Price:Available Copies:Sold Copies%s",ORS}
{flag=0}
$2 ~ a || $1 ~ t{flag=1;count++}flag
END{printf "Total Records - %s%s",count,ORS}' 48518186 | column -s':' -t
# Above, $author & $title are the variables you read using 'read'

<强>输出

Title              Author  Price  Available Copies  Sold Copies
jo                 jojo    2000   120               293
Total Records - 1

答案 4 :(得分:0)

您的代码会打印这两个条目,因为您没有指定“作者”,因此grep中的第二个grep -iE "^$title" BooksDB.txt | grep -iE "^[^:]+:$author"未过滤任何内容。 我建议您使用awk,因为您的文件包含:固有分隔符,这样可以使搜索更精确。

请注意,如果您未指定AuthorTitle字段,则不会将该字段用作过滤器。

示例:

function search_book
{
    echo "4) search_book"
    read -p "Title: " title
    read -p "Author: " author

    #searchtitle=` grep -i "^$title:$author:*" BooksDB.txt | cut -d: -f 1 `
###by using awk instead you only look for a title in the title column
    searchtitle=`awk -F':' -v t=$title 'BEGIN{IGNORECASE = 1} $1 ~ t {print $1}' BooksDB.txt`
    #searchauthor=` grep -i "^$title:$author:*" BooksDB.txt | cut -d: -f 2 `
    searchauthor=`awk -F':' -v a=$author 'BEGIN{IGNORECASE = 1} $2 ~ a {print $2}' BooksDB.txt`
    #If both searchtitle and searchauthor vars are empty, just say "No Books found."
    if [[ ! -z $searchtitle ]] && [[ ! -z $searchauthor ]]
    then
    recordcount=`awk -F':' -v t="$title" -v a="$author" 'BEGIN{IGNORECASE = 1} $1 ~ t && $2 ~ a {cnt++} END {print cnt}' BooksDB.txt`
    echo "Found $recordcount records"
    echo
    awk -F':' -v t="$title" -v a="$author" 'BEGIN{IGNORECASE = 1; print "Title:Author:Price:Available Copies:Sold Copies\n"}; $1 ~ t && $2 ~ a {print $0}' BooksDB.txt | column -s ":" -t
    echo
    else
    echo "No Books found."
    fi

}
search_book

答案 5 :(得分:0)

searchtitle=` grep -i "^$title+^[^:]+" BooksDB.txt | cut -d: -f 1 `
searchauthor=` grep -i "^[^:]+:$author" BooksDB.txt | cut -d: -f 2 `