Bash - 在嵌套的 [FOR, WHILE, IF] 语句中循环遍历数组

af.*_*.bj 3 bash

我正在尝试处理一个大文件集,将特定行附加到“test_result.txt”文件中 - 我使用以下代码实现了它 - 不是很优雅 - 。

for i in *merged; do
        while read -r lo; do
                if [[ $lo == *"ID"* ]]; then
                echo $lo >> test_result.txt
                fi
                if [[ $lo == *"Instance"* ]]; then
                echo $lo >> test_result.txt
                fi
                if [[ $lo == *"NOT"* ]]; then
                echo $lo >> test_result.txt
                fi
                if [[ $lo == *"AI"* ]]; then
                echo $lo >> test_result.txt
                fi
                if [[ $lo == *"Sitting"* ]]; then
                echo $lo >> test_result.txt

        done < $i
done
Run Code Online (Sandbox Code Playgroud)

但是,我正在尝试使用数组来缩小它的大小 - 这导致了一次非常不成功的尝试。

KEYWORDS=("ID" "Instance" "NOT" "AI" "Sitting" )
KEY_COUNT=0

for i in *merged; do
        while read -r lo; do
                if [[$lo == ${KEYWORDS[@]} ]]; then
                echo $lo >> ~/Desktop/test_result.txt && KEY_COUNT="`expr $KEY_COUNT + 1`"
                fi
        done < $i
done
Run Code Online (Sandbox Code Playgroud)

Kus*_*nda 5

看起来您想从一组文件中获取包含一组单词中至少一个单词的所有行。

假设你没有成千上万的文件,你可以用一个grep命令来做到这一点:

grep -wE '(ID|Instance|NOT|AI|Sitting)' ./*merged >outputfile
Run Code Online (Sandbox Code Playgroud)

这将从名称匹配的文件中提取与模式中列出的任何单词匹配的行*merged

所述-wgrep保证给定的字符串不作为子字符串(即匹配NOT将不被匹配NOTICE)。该-E选项启用模式中的交替|

-h如果您不希望输出中包含匹配行的文件名称,请将该选项添加到命令中。

如果您确实有数千个文件,则上述命令可能会因扩展到太长的命令行而失败。在这种情况下,您可能想要做类似的事情

for file in ./*merged; do
    grep -wE '(ID|Instance|NOT|AI|Sitting)' "$file"
done >outputfile
Run Code Online (Sandbox Code Playgroud)

它将grep在每个文件上运行一次命令,或者,

find . -maxdepth 1 -type f -name '*merged' \
    -exec grep -wE '(ID|Instance|NOT|AI|Sitting)' {} + >outputfile
Run Code Online (Sandbox Code Playgroud)

这将grep一次对尽可能多的文件进行尽可能少的调用。

有关的: