如何在 Linux 上使用 sed 或 awk 或 bash 脚本进行以下格式化

如何在 Linux 上使用 sed 或 awk 或 bash 脚本进行以下格式化

假设,我有两个文件:
file1具有以下内容。

消息_aaa.wav
  测试 1(共 1)
    测试标签:aaa
    测试句子:测试aaa
    测试字符串:测试消息
    口译得分:567
消息_bbb.wav
  测试 1(共 1)
    测试标签:bbb
    测试句子:测试 bbb
    测试字符串:测试 bbb
    口译分数:972
Message_ccc.wav
  测试 1(共 1)
    测试标签:ccc
    测试语句:ccc
    测试字符串:测试 ccc
    口译分数:921     
   

file2有以下内容:

消息_aaa.wav
  测试 1(共 1)
    测试标签:aaa
    测试句子:测试aaa
    测试字符串:测试消息
    口译分数:55
消息_bbb.wav
  测试 1(共 1)
    测试标签:bbb
    测试句子:测试 bbb
    测试字符串:测试 bbb
    口译分数:34
消息_ccc.wav
  测试 1(共 1)
    测试标签:ccc
    测试语句:ccc
    测试字符串:测试 ccc
    口译得分:12

我想创建一个CSV/xls文件,其中有 3 列:第一列将是文件
名称, 第二列将是“解释分数”, 第三列将是“解释分数”, 如下所示。 .wavfile1
from file1
from file2

message_aaa.wav,567,55
message_bbb.wav,972,34
message_ccc.wav,921,12

答案1

像这样的东西awk

awk '/^[mM]essage_.*.wav/{
    n=NR+5;i=tolower($1)
}
n==NR{
    a[i]=a[i]","$4
}
END{
    for ( i in a){
        print i""a[i]
    }
}' file1 file2

如果该行以[mM]essage_.*.wav变量n设置为NR+5(值所在的行号Interpretation Score) 开头,并且 wav 文件名保存在变量 a 中i

创建n==NR索引为 as 的数组时,将 ($4) 附加到该数组。iInterpretation Score

END根据需要打印所有数组索引及其值。

在这里,我假设该Interpretation Score行始终为每次测试中的第五行。

答案2

grep -e 'wav\|Inter' file1.txt | cut -d: -f2 | awk '{print $1}'| awk 'NR%2{printf $0",";next;}1' > file1new.txt
grep -e 'wav\|Inter' file2.txt | cut -d: -f2 | awk '{print $1}'| awk 'NR%2{printf $0",";next;}1' > file2new.txt
join -t, file1new.txt file2new.txt

  

答案3

这是一个可以完成这项工作的 Perl 脚本。它读取标准输入,并提取文件名以用作名为 的散列数组的密钥%wavfiles。使用的特定数据结构是数组散列,这是一种散列数组,其中每个元素都是包含一个或多个值的列表(即数组)。

当它看到与正则表达式匹配的行/Interpretation Score/并且 if$filename非空时,它会split()提取解释分数并将其推送到 中包含的数组中$wavfiles{$filename}。然后清除$filename以防止为该密钥添加虚假数据。

当没有更多输入需要读取时,它会以%wavfilesCSV 格式打印出数组哈希的内容。

该脚本可以处理任意数量、任意大小的输入文件。它将命令行上指定的所有文件名和/或从 stdin 传入的所有数据视为一个输入流。

输入的顺序很重要 - 它直接影响输出中解释分数的顺序(例如,如果它在 55 之前看到 567,这就是它将显示这些值的顺序。反之亦然)。

该脚本不仅限于每个文件名只有两个解释分数 - 它会打印每个文件名看到的尽可能多的解释分数,并按照看到它们的顺序用逗号分隔。

#! /usr/bin/perl

use strict;

my %wavfiles = ();
my $filename = '';

while(<>) {
    chomp;    # strip line-feed from end of line

    $filename = $_ if (m/\.wav$/);

    if ((m/Interpretation Score/) && (! -z $filename)) {
        my (undef,$score) = split /: /;     # split input line on ': '
        push @{ $wavfiles{$filename} }, $score;
        $filename = '';
    };
}   

foreach $filename (keys %wavfiles) {
    print "$filename,", join(",",@{ $wavfiles{$filename} }),"\n";
}   

使用示例输入的输出是:

$ ./interpscore.pl file1 file2
message_bbb.wav,972,34
Message_ccc.wav,921
message_aaa.wav,567,55
message_ccc.wav,12

请注意,哈希键与文件名一样区分大小写,这就是为什么有一个条目Message_ccc.wav(大写 -M)和message_ccc.wav(小写 -m) - 这就是输入文件中的内容。您需要编辑输入文件以使文件名一致 - 执行此操作后,输出将是:

$ ./interpscore.pl file1 file2
message_aaa.wav,567,55
message_ccc.wav,921,12
message_bbb.wav,972,34

相关内容