【问题标题】:How to match string values from text file in bash script如何在bash脚本中匹配文本文件中的字符串值
【发布时间】:2015-06-11 15:00:33
【问题描述】:

我正在尝试读取并显示文本文件中的每个单词,然后突出显示指定的元音或辅音。

当我从文件中读取时,我只能读取整行,所以我使用循环来读取行中的每个单词。但是,当我这样做时,我无法访问该单词中的不同位置。 (例如,如果单词是“happy”,我无法访问字母“a”的第二个位置)

#READS EACH LINE
while read line
    do
            #READS EACH WORD IN THE LINE
            for word in $line
            do
                    #LOOPS THROUGH EACH CHARACTER IN THE WORD
                    for (( i=0; i<${#word}; i++ ))
                    do
                            #LOOPS THROUGH ALL VALUES IN VOWEL ARRAY
                            for (( j=0; j<10; j++ ))
                            do
                                    #MATCHES IF A VOWEL IS FOUND
                                    if [ "${word[$i]}" == "${varray[$j]}" ]
                                    then
                                            let vcount++
                                            echo i:$i  j:$j
                                            echo word: ${word[$i]} varray: ${varray[$j]}    #DEBUG

                                    fi
                            done
                    done
                                            #MORE CODE HERE DOING STUFF PRINTING TO SCREEN
            done
    done < $file

我做错了什么吗? 还是我应该以不同的方式读取文件以访问单词的每个字符?

当我 echofor loop 中的单词时,它会将整个单词显示为第一个位置,而不仅仅是第一个字符。其余位置2、3等都是空的。

【问题讨论】:

    标签: arrays string bash file


    【解决方案1】:

    您似乎将数组索引与获取字符串的子字符串(“子字符串”,如果您愿意的话)混淆了。在我熟悉的每种编程语言中,这些都是完全不同的操作。在 bash 中,数组索引是通过 ${arr[index]} 形式的变量替换完成的。您需要的是 ${str:index:length} 形式的变量替换,它可以进行子字符串化。以下是如何使用它来使您的脚本工作:

    #!/bin/bash
    
    file='file';
    varray='aeiouy';
    
    #READS EACH LINE
    while read line; do
        #READS EACH WORD IN THE LINE
        for word in $line; do
            #LOOPS THROUGH EACH CHARACTER IN THE WORD
            for (( i=0; i<${#word}; i++ )); do
                #LOOPS THROUGH ALL VALUES IN VOWEL ARRAY
                for (( j=0; j<${#varray}; j++ )); do
                    #MATCHES IF A VOWEL IS FOUND
                    wordChar="${word:$i:1}";
                    vChar="${varray:$j:1}";
                    if [[ "$wordChar" == "$vChar" ]]; then
                        let vcount++;
                        echo "i:$i  j:$j";
                        echo "wordChar: $wordChar vChar: $vChar";
                    fi;
                done;
            done;
        done;
        #MORE CODE HERE DOING STUFF PRINTING TO SCREEN
    done <$file;
    
    exit 0;
    

    演示:

    cat file;
    ## abc def ghi
    ## jkl mno pqr
    
    ./script;
    ## i:0  j:0
    ## wordChar: a vChar: a
    ## i:1  j:1
    ## wordChar: e vChar: e
    ## i:2  j:2
    ## wordChar: i vChar: i
    ## i:2  j:3
    ## wordChar: o vChar: o
    

    其他说明:

    • 从文件中读取并将其分解为单词的代码就可以了。唯一需要注意的是read line 命令将丢失前导和尾随空格。这对你的脚本并不重要,但如果你想解决这个问题,你可以自己调用read,整行(包括前导和尾随空格)将默认读入$REPLY变量。
    • 在您的代码中,您将 j 从 0 迭代到 9,但最大值取决于 varray 的长度(实际上是一个字符串;可能应该重命名它),因此您应该使用 ${#varray} 作为最大。
    • 使用[[ ... ]] 代替旧的[ ... ] 形式进行表达式评估;较新的形式稍微强大一些。

    【讨论】:

    • 感谢您的回答,它对我来说更清楚了一些事情。我设法让我的脚本匹配元音:D。现在,当我根据元音的数量添加具有不同条件的 IF 语句时,无论是否有 1、2 或没有元音,它总是输入相同的 IF 语句?
    猜你喜欢
    • 2011-02-09
    • 2013-03-02
    • 2015-03-29
    • 1970-01-01
    • 2012-04-21
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    • 2021-10-24
    相关资源
    最近更新 更多