我有一个包含 +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