在结果文件中的FOR循环中打印处理文件名 - BASH

时间:2017-09-08 08:14:50

标签: bash

我在bash文件中运行for循环,该文件将检查某些特定字符串的文件(.ts)并在结果文件中打印匹配的行。

以下是代码:

#! /bin/bash

for file in *.ts;
do awk -f test_function.awk $file > result.txt;
done

这是test_function.awk文件:

match($0, /<name>(.*)<\/name>/,n){ nm=n[1] }
match($0, /<source>(.*)<\/source>/,s){ src=s[1] }
/unfinished/{ print "name: " nm, "source: " src }

这是包含&#34;未完成&#34;的输入文件之一并且需要包含在输出中:

<context>
    <name>AccuCapacityApp</name>
    <message>
        <source>Capacity</source>
        <translation type="unfinished">Kapazität</translation>
    </message>
    <message>
        <source>Charge Level</source>
        <translation type="unfinished"></translation>
    </message>
    <message>
        <source>Sel (Yes)</source>
        <translation type="unfinished">Sel (Ja)</translation>
    </message>
    <message>
        <source>Esc (No)</source>
        <translation type="unfinished">Esc (Nein)</translation>
    </message>
</context>

它提供如下输出:

name: AccuCapacityApp source: Capacity
name: AccuCapacityApp source: Charge Level
name: AccuCapacityApp source: Sel (Yes)

这是一个不包含&#34;未完成&#34;的输入文件之一。并且需要从输出中排除:

<context>
    <name>ATM FSM state</name>
    <message>
        <source>Hunting</source>
        <translation>Sync-Suche</translation>
    </message>
    <message>
        <source>Pre-Sync</source>
        <translation>Pre-Sync</translation>
    </message>
    <message>
        <source>Sync</source>
        <translation>Sync</translation>
    </message>
</context>

我想要做的是在结果文件中匹配行的每个段落的开头打印处理文件名,仅在找到匹配的字符串时,如下所示:

Processign file: alpha.txt
name: AccuCapacityApp source: Capacity
name: AccuCapacityApp source: Charge Level
name: AccuCapacityApp source: Sel (Yes)

Processing file: gamma.txt
name: AccuCapacityApp source: Capacity
name: AccuCapacityApp source: Charge Level
name: AccuCapacityApp source: Sel (Yes)

我怎样才能做到这一点?

我知道可以附加文件名,然后匹配的行可以附加到结果文件中。但是我希望每次运行bash文件时都有一个空白的结果文件,并且只在找到匹配的字符串时才写入文件名和内容。所以我认为附加文件名是行不通的。我尝试使用echo ${file##*/}echo $file{print FILENAME};{print "\t" $0}打印文件名,但无法根据需要进行打印。

1 个答案:

答案 0 :(得分:1)

根据您的更新,我认为这可以满足您的需求:

match($0, /<name>(.*)<\/name>/,m){ nm = m[1] }
match($0, /<source>(.*)<\/source>/,m){ src = m[1] }
/unfinished/ { list[++n] = src }
ENDFILE {
    for (i = 1; i <= n; ++i) {
        print "name:", nm, "source:", list[i]
    }
    n = 0
}

仅在找到unfinished时保存元素,循环遍历每个文件末尾的列表。 n会保留当前文件中匹配项的数量。

使用这样的脚本(不需要shell循环):

awk -f test_function.awk *.ts > result.txt

请注意ENDFILE是一个GNU awk扩展,但是你已经使用的match的第三个参数也是如此,所以我猜你没关系。