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

时间:2012-05-11 13:25:20

标签: sed awk

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

 1PPYA
 2PPYB
 1GBND
 1CVHA

此文件的第一行是“1PPYA”。我想

  1. 阅读“1PPYA”的最后一个字符。在这个例子中,它是“A /”
  2. 从“yy”目录中找到“1PPY.txt”(前四个字符)。
  3. 删除以“csh”开头的行,其中包含“A”字符。
  4. 在“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 
    

4 个答案:

答案 0 :(得分:1)

假设你的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

正如你用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

答案 1 :(得分:0)

您可以使用此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)

我发布此信息是因为您是新用户,但向我们展示您尝试过的内容以及您遇到的位置会更好。

答案 2 :(得分:0)

这可能对您有用:

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

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

答案 3 :(得分:0)

TXR:

@(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)

由于外部@(collect)/@(end)(很容易删除),因此会处理来自xx.txt的所有行,而不仅仅是第一行,因此它会爆炸,因为我没有{{1} }。