如果在行的前 12 个字符中找到列表中的字符串,则从大文件中删除行?

如果在行的前 12 个字符中找到列表中的字符串,则从大文件中删除行?

我有一个包含 +184000 行 * +5400 行的文件矩阵,如下所示

denovo1 someverylaaargenumbers and lotandlotsoftextuntil 5400.........
denovo10 someverylaaargenumbers and lotandlotsoftextuntil 5400........
denovo100 someverylaaargenumbers and lotandlotsoftextuntil 5400.......
denovo1000 someverylaaargenumbers and lotandlotsoftextuntil 5400......
denovo10000 someverylaaargenumbers and lotandlotsoftextuntil 5400.....
denovo100000 someverylaaargenumbers and lotandlotsoftextuntil 5400......
denovo184117 someverylaaargenumbers and lotandlotsoftextuntil 5400......

我在第二个文件中有一个标识符列表,如下所示:

denovo1
denovo100
denovo1000
denovo100000

如果在文件 2 中找到标识符,我希望清除矩阵 1 中的行。因此:

denovo10 someverylaaargenumbers and lotandlotsoftextuntil 5400........
denovo10000 someverylaaargenumbers and lotandlotsoftextuntil 5400.....
denovo184117 someverylaaargenumbers and lotandlotsoftextuntil 5400......

我有这段简短的 unix 代码,它逐行读取并查找文件 2 中的字符串:

while read -r line
do
echo $line
sed -i '' '/$line/d' /my/path/matrix1
done < /my/path/file2

它确实有效,但需要很长时间,因为它会将所有行读到底。有没有办法让机器只读取每行的前12个字符?

答案1

grep

grep -vwf file matrix > matrix.new
mv matrix.new matrix
  • 选项-f FILE用作FILE模式输入文件
  • 选项-w仅选择包含形成整个单词的匹配的行
  • 选项-v选择不匹配的行

请注意,file不得包含任何空行。

或者,如果您手动创建标识符文件,其中使用锚点^来匹配行的开头,并在每个标识符后面添加一个空格字符来标记模式的结尾:

printf '^%s \n' denovo{1,100,1000,100000} > file
grep -vf file matrix > matrix.new
mv matrix.new matrix

答案2

尝试:

$ awk 'FNR==NR{ids[$1]; next} !($1 in ids)' ids file
denovo10 someverylaaargenumbers and lotandlotsoftextuntil 5400........
denovo10000 someverylaaargenumbers and lotandlotsoftextuntil 5400.....
denovo184117 someverylaaargenumbers and lotandlotsoftextuntil 5400......

怎么运行的:

  • FNR==NR{ids[$1]; next}

    在读取第一个文件 时,这会在带有 id 的ids关联数组中创建一个键。ids然后它会跳过其余命令并跳转到该next行。

  • !($1 in ids)

    在读取第二个文件时,如果第一个字段不是关联数组中的键,则会打印该行ids

更新原始文件

当您对代码正常工作感到满意时,可以更改该文件:

awk 'FNR==NR{ids[$1]; next} !($1 in ids)' ids file >tmp && mv tmp file

相关内容