使用sed只返回包含特定字符串的最后一行

时间:2014-06-10 12:13:48

标签: linux text sed

所有的帮助将不胜感激,因为我尝试了很多谷歌搜索,并留下了空白:)

我是sed的新手,不知道我需要的命令是什么。

我有一个包含多行的文件,例如

John Smith Aweqwewq321
Mike Smith A2345613213
Jim Smith Ad432143432
Jane Smith A432434324
John Smith Bweqwewq321
Mike Smith B2345613213
Jim Smith Bd432143432
Jane Smith B432434324
John Smith Cweqwewq321
Mike Smith C2345613213
Jim Smith Cd432143432
Jane Smith C432434324

该文件是纯文本,未格式化(即不是csv或类似的东西)

我想搜索特定字符串的列表,例如。 John Smith,Mike Smith,Jim Smith并且只返回文件中找到的每个字符串的最后一行条目(找到的所有其他行都将被删除)。

(我不一定需要每个唯一的条目,即可能需要或不需要Jane Smith)

重要的是,找到的行的原始顺序保留在输出中。

结果将是:

John Smith Cweqwewq321
Mike Smith C2345613213
Jim Smith Cd432143432

我是sed的新手,不知道这个命令可能是什么。

大约有100个特定搜索字符串。

谢谢:)

4 个答案:

答案 0 :(得分:1)

假设sample.txt包含您提供的数据:

$ cat sample.txt
John Smith Aweqwewq321
Mike Smith A2345613213
Jim Smith Ad432143432
Jane Smith A432434324
John Smith Bweqwewq321
Mike Smith B2345613213
Jim Smith Bd432143432
Jane Smith B432434324
John Smith Cweqwewq321
Mike Smith C2345613213
Jim Smith Cd432143432
Jane Smith C432434324

对于此示例数据,以下脚本可以正常工作:

$ cut -f1,2 -d' ' sample.txt  | sort | uniq | while read s; do tac sample.txt | grep -m1 -n -e "$s" ; done | sort -n -r -t':' | cut -f2 -d':'

John Smith Cweqwewq321
Mike Smith C2345613213
Jim Smith Cd432143432
Jane Smith C432434324

以下是剧本的细分:

  • 首先生成所有唯一字符串(在这种情况下为名字,姓氏)
  • 现在找到每个字符串的最后一个匹配项。为此,我们通过反转文件找到第一次出现。同时打印行号和输出。
  • 现在以反向行号顺序反转输出,然后删除行号(我们不需要它们)

答案 1 :(得分:0)

  • 您没有告诉给定列表的格式,我认为它是CSV,与您在相关时写的相同:eg. John Smith, Mike Smith, Jim Smith

  • 根据您的描述,您需要行each string found,而不仅仅是col1和col2

从以上两点来看,我有:

awk -v list="John Smith, Mike Smith, Jim Smith" 'BEGIN{split(list,p,",\\s*")}
    {for(i=1;i<=length(p);i++){
        if($0~p[i]){
            a[p[i]]=$0
            break
        }
    }
}END{for(x in a)print a[x]}' file

你可以用你的字符串填充list,用逗号分隔。用测试数据输出:

John Smith Cweqwewq321
Mike Smith C2345613213
Jim Smith Cd432143432

答案 2 :(得分:0)

反转列表,例如像这样的东西:

$ sed -n '/Mike/{p;q}' <(tac input.txt)
Mike Smith C2345613213

答案 3 :(得分:0)

sed -n -e 's/.*/&³/
H
$ {x
   s/\n/²/g
   t a
:a
   s/²\([a-zA-Z]* [a-zA-Z]* \)[^³]*³\(\(.*\)²\1\)/\2/
   t a
   s/²//g;s/³$//;s/³/\
/g
   p
   }' YourFile

使用任何名称(不能包含²³)。对于具有[-a-z-A-Z]

的组合名称更改模式

在您的列表中,还有Jane Smith至少出现一次

对于特定列表,请先使用grep -f,在不更改代码的情况下更快,更容易维护