从文件中只读取一部分模式

时间:2018-05-15 19:06:21

标签: bash shell grep pattern-matching

我有一个文件中的字符串列表。我想找出添加到特定前缀的哪些字符串在另一个文件中不存在。

所以如果字符串列表是这样的

foo
bar
baz
qux

目标文件是这个

prefix-foo
prefix-barnotreally
prefix-baz

命令的输出应为

bar
qux

我知道-f grep标志,但据我所知,它不允许用户使用文件中的字符串作为模式的一部分

5 个答案:

答案 0 :(得分:1)

您可以使用流程替换从第二个文件中提取字符串的一部分,以传递给-f的{​​{1}}选项:

grep
  • grep -vxFf <(cut -f2- -d- file2) file1 - 反向搜索;找到与
  • 不匹配的行
  • -v - 匹配整行
  • -x - 寻找字符串,而不是正则表达式
  • -F - 从目标文件中提取字符串,留下前缀

答案 1 :(得分:1)

另一种选择是使用标准的Unix工具join

join -t- -1 1 -2 2 -v 1 <(sort file1) <(sort -t- -k 2 file2)

该命令在某个连接字段上连接两个表。它需要通过join字段对两个文件进行排序,这就是我们需要两个sort命令的原因。我们还可以通过使用临时文件使其更具可读性:

sort file1 > file1.sorted
sort -t- -k 2 file2 > file2.sorted
join -t- -1 1 -2 2 -v 1 file1.sorted file2.sorted

第一个sort命令只是对文件的行进行排序。第二个排序命令按第二个字段(-k 2)排序,使用短划线作为字段分隔符(-t-)。

join命令还指定-作为字段分隔符(-t-),并选择第一个文件中的第一列作为连接键(-1 1),并且第二个文件中的第二列(-2 2)。输出仅限于第一个文件(-v 1)中的不可用行。

如果您的文件非常大,这个解决方案比其他任何文件都更有效,但在大多数实际情况下,性能差异不应该太大。

答案 2 :(得分:0)

如果您熟悉它,可以使用awk。这是一个例子:

$ cat test.data
prefix-foo
prefix-barnotreally
prefix-baz
$ cat test.awk
BEGIN {
    split("foo bar baz qux", a);
}

/^prefix-*/ {
    gsub("^prefix-", "");
    for (i in a)
        if ($0 == a[i])
            found[$0] = ""
}

END {
    for (i in a)
        if (!(a[i] in found))
            print a[i]
}
$ awk -f test.awk test.data
bar
qux

答案 3 :(得分:0)

您可以使用bash脚本作为第一个参数接收包含该格式的字符串的文件,并使用该格式的文本文件作为第二个参数

#! /bin/bash

if [ $# -ne 2 ]; then
    echo "Usage: $0 <file1> <file2>"
    exit 1
fi

fStrings=$1
file=$2

while read string; do
    cat $file | grep -qw $string
    if [ $? -ne 0 ]; then
        echo $string
    fi
done < $fStrings

答案 4 :(得分:0)

使用awk

private class Dev : Constant<string>
{
    public Dev() : base("DEV")
    {
    }
}

[PXSelector(typeof(Search<EPEmployeePosition.employeeID, 
                   Where<EPEmployeePosition.positionID, 
                   Equal<Dev>>>))]

获取字符串a中的所有目标文件,而不打印字符串a中找到的列表字符串