以错误的方式使用awk

时间:2016-08-13 03:51:16

标签: bash shell awk

我被告知在下面的代码中我使用了awk的错误方法,但我对于如何改进我的代码以使其更简单易读而感到茫然。

read -r bookName
read -r authorName

if grep -iqx "$bookName:$authorName" cutText.txt
then
    lineNum=`awk -v bookName="$bookName" -v authorName="$authorName" '$0 ~ bookName ":" authorName {print NR} BEGIN{IGNORECASE=1}' BookDB.txt`

    echo "Enter a new title"
    read -r newTitle

    awk -F":" -v bookName="$bookName" -v newTitle="$newTitle" -v lineNum="$lineNum" 'NR==lineNum{gsub(bookName, newTitle)}1' cutText.txt > temp2.txt
    mv -f temp2.txt cutText.txt
else
echo "Error"
fi

我的cutText.txt包含如下所示的内容:

Hairy Potter:Rihanna
MARY IS A LITTLE LAMB:Kenny
Sing along:May

该程序基本上更新了cutText.txt中的新标题。如果用户想要将MARY IS A LITTLE LAMB更改为Mary is not a lamb,他将输入新标题,cutText.txt将用Mary is not a lamb替换原始标题。

现在出现一个问题,即如果用户为$newTitle输入“Mary is a little lamb”,则此代码无效,因为它确实考虑了这种情况。 只有用户类型“MARY IS LITTLE LAMB”才能使用它。我开始意识到BEGIN{IGNORECASE=1}是gawk-sepcific,因此它不能用于awk。

如何更好地编写脚本以便我可以忽略用户输入中的大小写?谢谢!

2 个答案:

答案 0 :(得分:1)

让你入门。创建文件

<强> r.awk

function asplit(str, arr, sep,   temp, i, n) {  # make an assoc array from str
    n = split(str, temp, sep)
    for (i = 1; i <= n; i++)
        arr[temp[i]]++
    return n
}

function regexpify(s,   back, quote, rest, all, meta, n, c, u, l, ans) { 
    back = "\\"; quote = "\"";
    rest = "^$.[]|()*+?"
    all  = back quote rest
    asplit(all, meta, "")

    n = length(s)
    for (i=1; i<=n; i++) {
    c = substr(s, i, 1)
    if      (c in meta)
        ans = ans back c
    else if ((u = toupper(c)) != (l = tolower(c)))
        ans = ans "[" l u "]"
    else
        ans = ans c
    }

    return ans
}

BEGIN {
    old = regexpify(old)
    sep = ":"; m = length(sep)
}

NR == n {
    i = index($0, sep)
    fst = substr($0,   1, i-m)
    scn = substr($0, i+m     )

    gsub(old, new, fst)
    print fst sep scn

    next
}

{
    print
}

<强> cutText.txt

Hairy Potter:Rihanna
MARY IS A LITTLE LAMB:Kenny
Sing along:May

用法:

awk -v n=2 -v old="MArY iS A LIttLE lAmb" -v new="Mary is not a lamb" -f r.awk  cutText.txt 

预期产出:

Hairy Potter:Rihanna
Mary is not a lamb:Kenny
Sing along:May

答案 1 :(得分:0)

好的我刚刚实现了我的DUMB作为****

我整天都在撕扯我的头发,我所要做的就是做到这一点。

lineNum=`grep -in "$bookName:$authorName" BookDB.txt | cut -f1 -d":"`

sed -i "${lineNum}s/$bookName/$newTitle/I" BookDB.txt cutText.txt

哦,我觉得自杀了。