使用awk或sed根据另一个文件中的最后一个字符从文本文件中删除行

使用awk或sed根据另一个文件中的最后一个字符从文本文件中删除行,sed,awk,Sed,Awk,我有一个文件,xx.txt,像这样 1PPYA 2PPYB 1GBND 1CVHA 该文件的第一行是“1PPYA”。我想 阅读“1PPYA”的最后一个字符。在本例中,它是“A/” 从“yy”目录中查找“1PPY.txt”(前四个字符) 删除以“csh”开头并包含“A”字符的行 给定“yy”目录中的以下“1PPY.txt”: csh 1 A 1 27.704 6.347 csh 2 A 1 28.832 5.5

我有一个文件,xx.txt,像这样

 1PPYA
 2PPYB
 1GBND
 1CVHA
该文件的第一行是“1PPYA”。我想

  • 阅读“1PPYA”的最后一个字符。在本例中,它是“A/”
  • 从“yy”目录中查找“1PPY.txt”(前四个字符)
  • 删除以“csh”开头并包含“A”字符的行
  • 给定“yy”目录中的以下“1PPY.txt”:

     csh    1      A   1      27.704   6.347   
     csh    2      A   1      28.832   5.553  
     csh    3      A   1      28.324   4.589 
     csh    4      B   1      27.506   3.695  
     csh    5      C   1      29.411   4.842 
     csh    6      A   1      28.378   4.899  
    
    所需的产出将是:

    csh  4      B   1      27.506   3.695
    csh  5      C   1      29.411   4.842 
    

    您可以使用以下bash脚本:

    while read f l
    do
       [[ -f $f ]] && awk -v l=$l '$3 != l' $f
    done < <(awk '{len=length($0);l=substr($0,len);f=substr($0,0,len-1);print "yy/" f ".txt", l;}' xx.txt)
    
    读取f l时
    做
    [[-f$f]]&&awk-vl=$l'$3!=l'$f
    
    完成<这可能适合您:

     sed 's|^ *\(.*\)\(.\)$|sed -i.bak "/^ *csh.*\2/d" yy/\1.txt|' xx.txt | sh
    

    注意,我添加了一个文件备份。如果不需要,则将
    -i.bak
    修改为
    -i

    假设您的shell是bash

    while read word; do
        if [[ $word =~ ^(....)(.)$ ]]; then
            filename="yy/${BASH_REMATCH[1]}.txt"
            letter=${BASH_REMATCH[2]} 
            if [[ -f "$filename" ]]; then
                sed "/^csh.*$letter/d" "$filename"
            fi
        fi
    done < xx.txt
    
    读单词时
    ;做
    如果[[$word=~^(..)(..$]);然后
    filename=“yy/${BASH_重新匹配[1]}.txt”
    字母=${BASH_重赛[2]}
    如果[-f“$filename”];然后
    sed“^csh.*$letter/d”“$filename”
    fi
    fi
    完成
    正如您用awk标记问题:

    awk '{
        filename = "yy/" substr($1,1,4) ".txt"
        letter = substr($1,5)
        while (getline < filename) 
            if (! match($0, "^csh.*" letter)) 
                print
        close(filename)
    }' xx.txt
    
    awk'{
    filename=“yy/”substr($1,1,4)”.txt
    字母=substr($1,5)
    while(getline
    TXR:

    运行:


    由于外部的
    @(collect)/@(end)
    (很容易删除),这将处理
    xx.txt
    中的所有行,而不仅仅是第一行,因此它会爆炸,因为我没有
    2PPY.txt
    ,您希望用户现在就为您的项目投标吗?首先告诉我们您遇到了什么困难。请告诉我们您尝试了什么,然后我们可以帮助您。+1-您可能需要Bash版本中的
    sed-i
    。以及在AWK版本中进行重定向/重命名。(假设OP不需要一个输出流)
    @(next "xx.txt")
    @(collect)
    @*prefix@{suffix /./}
    @  (next `yy/@prefix.txt`)
    @  (collect)
    @    (all)
    @{whole-line}
    @    (and)
    @      (none)
    @shell @num @suffix @(skip)
    @      (end)
    @    (end)
    @  (do (put-string whole-line) (put-string "\n"))
    @  (end)
    @(end)
    
    $ txr del.txr
    csh    4      B   1      27.506   3.695  
    csh    5      C   1      29.411   4.842 
    txr: unhandled exception of type file_error:
    txr: (del.txr:5) could not open yy/2PPY.txt (error 2/No such file or directory)