在读取行循环时重击不会在条件下打印每一行

时间:2019-03-10 15:14:03

标签: bash awk

我有以下情况:

我有一个文本文件正在尝试循环,因此我可以知道在这种情况下每一行是否都与“ .mp3”匹配:

let data = [
    {
        rowNumber: 1,
        specification: null,
        validationMessage: [
            {
                isExists: true,
                errors: [
                    {
                        errorCode: "PredicateValidator",
                        errorMessage: "ERR: Length value is not in correct  "
                    },
                    {
                        errorCode: "PredicateValidator",
                        errorMessage: "Height Unit is not in correct  "
                    },
                ]
            }
        ]
    },
    {
        rowNumber: 2,
        specification: null,
        validationMessage: [
            {
                isExists: false,
                errors: []
            }
        ]
    },
]


let newarr = data.filter(x=>x.validationMessage[0].errors.find(a=>a.errorMessage.includes('ERR:')))

let isError = data.some(x=>x.validationMessage[0].errors.find(a=>a.errorMessage.includes('ERR:')))

console.log(isError)

console.log(newarr)

因此,我编写了以下脚本来对其进行处理:

12 Stones.mp3
randomfile.txt
Aclarion.mp3
ransomwebpage.html
Agents Of The Sun.mp3
randomvideo.mp4

预期输出为:

while read line || [ -n "$line" ]
do
varline=$(awk '/.mp3/{print "yes";next}{print "no"}')
echo $varline
if [ "$varline" == "yes" ]; then
        some-command
    else
         some-command
    fi
done < file.txt

相反,似乎错过了第一行,我得到了以下信息:

yes
no
yes
no
yes
no

3 个答案:

答案 0 :(得分:3)

如果您仅使用Awk,那么您真的不需要Awk进行简单的模式匹配。

while IFS= read -r line; do
    case $line in
     *.mp3) some-command;,
     *) some-other-command;;
    esac
done <file.txt

如果出于其他原因仍在使用Awk,则在shell循环中循环行效率很低,而且通常是反模式。这并不能真正解决问题,但至少避免了在每次迭代中执行新的Awk实例:

awk '{ print ($0 ~ /\.mp3$/) ? "yes" : no" }' file.txt |
while IFS= read -r whether; do
    case $whether in
     'yes') some-command ;;
     'no') some-other-command;;
    esac
done

如果您还需要"$line"的内容,那么也可以从Awk打印该内容并读取两个不同的变量。

我简化了read表达式,并假设您可以确保输入文件的格式正确。如果您不能这样做,则需要在文件的最后一行放回更复杂的保护措施,以防止缺少换行符。

答案 1 :(得分:2)

使用awk

$ awk '{if ($0 ~ /mp3/) {print "yes"} else {print "no"}}' file.txt
yes
no
yes
no
yes
no

或更简洁:

$ awk '/mp3/{print "yes";next}{print "no"}' file.txt
$ awk '{print (/mp3/ ? "yes" : "no")}' file.txt

答案 2 :(得分:2)

您忘记了什么吗?您的awk没有明确的输入,请改为以下内容:

while IFS= read -r read line || [ -n "$line" ]
do
varline=$(echo "$line" | awk '/.mp3/{print "yes";next}{print "no"}')
echo $varline
if [ "$varline" == "yes" ]; then
        some-command
    else
        some-other-command
    fi
done < file.txt

在这种情况下,您可能需要更改为/\.mp3$//\.mp3[[:space:]]*$/才能进行精确匹配。
因为.可以匹配任何字符,所以例如/.mp3/也可以匹配Exmp3but.mp4
更新:将while read line更改为while IFS= read -r read line,以在分配给变量时保持每一行的内容不变。

awk部分可以改进为:

awk '{print $0~/\.mp3$/ ? "yes":"no"}'

因此仅使用awk,您可以这样做:

awk '{print $0~/\.mp3$/ ? "yes":"no"}' file.txt

或者如果您的目的只是if结构中的命令,则可以执行以下操作:

awk '/\.mp3$/{system("some-command");next}{system("some-other-command");}' file.txt

或者这个:

awk '{system($0~/\.mp3$/ ? "some-command" : "some-other-command")}' file.txt