读取行循环时Bash不打印条件中的每一行

问题描述 投票:2回答:3

我有以下情况:

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

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

相反,它似乎错过了第一行,我得到以下内容:

no
yes
no
yes
no
bash awk
3个回答
4
投票

你真的不需要使用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表达式,假设您可以确保输入文件是单独格式良好的。如果你不能这样做,你需要在文件的最后一行放回更复杂的防范,以防丢失的换行符。


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
投票

你忘记了什么吗?你的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
© www.soinside.com 2019 - 2024. All rights reserved.