如何在shell脚本中使用grep但不使用for循环来执行以下任务?

2024-05-23 19:35:30 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个文件,比如a.txt,大约有80000行,但是有两个字段。示例行如下所示:

utt1 f 
utt2 f 
utt3 m 
utt4 f

我有第二个文件B.txt,它比a.txt有更多的行,有两个字段。示例行如下所示

utt1_1 somethingHere    
utt1_2 somethingElse    
utt2_1 someText    
utt2_2 somemore    
utt2_3 someMore    
utt3_1 someText    
utt4_1 somemore    
utt4_2 abcd    
utt4_3 aanan

B.txt中的第一个字段基本上与A.txt中的第一个字段相同,后面跟一些东西(每行重复的次数是可变的)。你知道吗

我的任务是制作一个这样的文件

utt1_1 f    
utt1_2 f    
utt2_1 f    
utt2_2 f    
utt2_3 f    
utt3_1 m    
utt4_1 f    
utt4_2 f    
utt4_3 f

“f”和“m”开始表示性别。换句话说,我想做的是从A.txt和grep中获取B.txt中的utt和性别信息,并用正确的性别映射第一个字段。我使用while循环来实现它,如下所示:

while read utt gen; do
   grep $utt B.txt | awk -v gen=$gen '{print $1" "gen}'
done < A.txt

因为,我是在一个循环中做的,而且a.txt的长度很大,所以完成这个任务要花很多时间。你能给我一个更快的方法来使用bash吗?你知道吗

谢谢


Tags: 文件txt示例grepgen性别whileutt
3条回答
awk '$1 !~ /_/ { lst[$1]=$2 } $1 ~ /_/ { print $1" "lst[substr($1,1,4)] }' file1 file2

如果文件中包含的字段与\模式不匹配,则将它们添加到数组中,否则打印每个文件中的第一个字符串以及我们创建的数组中的值。你知道吗

另一个在awk中,这次使用split

$ awk 'NR==FNR{a[$1]=$2;next}{split($1,b,"_");if(i=b[1] in a)print $1,a[b[1]]}' file1 file2
utt1_1 f
utt1_2 f
utt2_1 f
utt2_2 f
utt2_3 f
utt3_1 m
utt4_1 f
utt4_2 f
utt4_3 f

说明:

NR==FNR {                   # process the first file
    a[$1]=$2                # hash it to a hash with $2 as value
    next }                  # move to next record
{                           # process the second (or any number of) file
    split($1,b,"_")         # split the $1 on _ 
    if(i=b[1] in a)         # first part of b is the key to hash
        print $1,a[b[1]] }  # output $1 and hash value
' file1 file2

这是为awk2文件处理量身定做的作业:

awk 'FNR == NR {a[$1] = $2; next} $1 in a {print $1 "_" $2, a[$1]}' file1 FS='[_ ]' file2
utt1_1 f
utt1_2 f
utt2_1 f
utt2_2 f
utt2_3 f
utt3_1 m
utt4_1 f
utt4_2 f
utt4_3 f

参数file1 FS='[_ ]' file2仅为file2设置输入字段分隔符_或空格。你知道吗

参考:Effective AWK Programming

相关问题 更多 >