【问题标题】:Generate a new file based on a condition + column matching of two files根据两个文件的条件+列匹配生成新文件
【发布时间】:2018-01-02 19:09:19
【问题描述】:

首先,如果我在发布之前没有遇到类似的答案,我深表歉意。

我正在尝试根据几个条件创建第三个文件。

我有两个输入文件

file1(制表符分隔):-

X_ID1 y_id11 num1
X_ID2 y_id31 num2  
X_ID3 y_id34 num3 
X_ID4 y_id23 num4
X_ID5 y_id2  num5 
...  
...  

文件 2:-

BIOTIC AND ABIOTIC STRESS
x_id2
REGULATION OF TRANSCRIPTION
x_id1
x_id4
HORMONES
x_id5
REGULATION
x_id6
x_id13
...
...

****请注意,文件 1 的第 1 列是大写的,文件 2 中的数据是小写的

我想要的是有一个输出文件(file3)如下:-

BIOTIC AND ABIOTIC STRESS
y_id31
REGULATION OF TRANSCRIPTION
y_id11
y_id23
HORMONES
y_id2
...
...

基本上,如果我想到一个“伪代码”,它会如下所示:-

while read $line from file2; do
 if [[line1 != x_*]]; then
    print $line
 else
    match $line (case insensitively) with column 1 of file1 and print respective column2 of file1
 fi
done 

您能帮我解决这个问题吗?

提前非常感谢!

【问题讨论】:

    标签: bash if-statement awk sed while-loop


    【解决方案1】:

    在 awk 中:

    $ awk 'NR==FNR{a[tolower($1)]=$2;next}{print ($1 in a?a[$1]:$0)}' file1 file2
    BIOTIC AND ABIOTIC STRESS
    y_id31
    REGULATION OF TRANSCRIPTION
    y_id11
    y_id23
    HORMONES
    y_id2
    REGULATION
    x_id6
    x_id13
    

    解释:

    $ awk '
    NR==FNR {                    # first file
        a[tolower($1)]=$2        # hash to a, key is lowercase $1 data is $2
        next                     # skip tp next record
    }
    {                            # second file
        print ($1 in a?a[$1]:$0) # if $1 exists in hash a, print it, else print current
    }' file1 file2               # mind the order
    

    根据@Sundeep 的建议,this 是 awk 中两个文件处理的一个很好的介绍。

    【讨论】:

    • 非常感谢您的解释和解释。当您无需盲目地运行代码就能理解解释中的内容时,那就太好了。是的,它有效! :)
    【解决方案2】:
    OLD_IFS="${IFS}"
    IFS=$'\n'
    for line in `cat file2`
    do
            if [[ -z `echo "${line}" | grep x_*`  ]]
            then
                    echo "${line}"
            else
                    grep -i "${line}" file1 | awk -F ' ' '{print $2}'
            fi
    done
    IFS="${OLD_IFS}"
    

    【讨论】:

    【解决方案3】:

    可以通过一个while循环来完成:-

    while IFS= read -r line;
    do
       var=`echo $line | tr '[a-z]' '[A-Z]'`
       col2=`grep "$var" file1|cut -d" " -f2`
       if [[ -z "$col2" ]] ; then
            echo "$line" >> file3
        else
            echo "$col2"  >> file3
       fi
    
    done < file2
    

    解释:-

    var=echo $line | tr '[a-z]' '[A-Z]' - 将小写转换为大写。

    col2=grep "$var" file1|cut -d" " -f2 - 匹配来自 file1 的模式。如果不匹配,即变量 col2 为空,则将行写入文件 file3 否则将 col2 写入文件。

    【讨论】:

      猜你喜欢
      • 2018-08-23
      • 1970-01-01
      • 2019-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多