我有两个文本文件都有索引行。我想比较file1和file2,并将类似的行发送到新的文本文件。我一直在谷歌上搜索一段时间,并尝试各种形式的grep,但我觉得我已经超过了我的头脑。我最终希望看到file2中出现的'Mon - ######'出现在file1中并打印出来自file1的相应行。
(文件要大得多,我为了简洁起见将它们剪下来)
更清晰:
file1具有以下形式的条目:
Mon-000101 100.27242 9.608597 11.082 10.034
Mon-000102 100.18012 9.520860 12.296 12.223
file2包含以下格式的条目:
Mon-000101
Mon-000171
因此,如果file1中列出了来自file2的标识符(例如Mon-000101),我希望将以Mon-000101开头的整行打印到单独的文件中。如果它没有在file2中列出,则可以将其丢弃。
因此,如果文件仅与上述文件一样大,则新生成的文件将具有单个条目
Mon-000101 100.27242 9.608597 11.082 10.034
因为这是两者共有的唯一共同点。
答案 0 :(得分:1)
$ join <(sort file1) <(sort file2) > duplicated-lines
答案 1 :(得分:1)
既然你添加了python标签,你似乎想要这样的东西:
import csv
f = open('file2')
l = set([l.strip() for l in f.readlines()])
with open('file1', 'rb') as csvfile:
dialect = csv.Sniffer().sniff(csvfile.read(10024))
csvfile.seek(0)
reader = csv.reader(csvfile, dialect)
cnt = 0
for item in reader:
if cnt >0:
data = item[0]
if data in l:
print item
cnt = cnt + 1
答案 2 :(得分:0)
从早期的问题开始,你至少对pandas有点熟悉,如何:
import pandas as pd
df1 = pd.read_csv("file1.csv", sep=r"\s+")
df2 = pd.read_csv("file2.csv", sep=r"\s+")
merged = df1.merge(df2.rename_axis({"Mon-id": "NAME"}))
merged.to_csv("merged.csv", index=False)
一些解释(请注意我已经修改了file2.csv
,以便共同拥有更多元素)。
首先,阅读数据:
>>> import pandas as pd
>>> df1 = pd.read_csv("file1.csv", sep=r"\s+")
>>> df2 = pd.read_csv("file2.csv", sep=r"\s+")
>>> df1.head()
NAME RA DEC Mean_I1 Mean_I2
0 Mon-000101 100.27242 9.608597 11.082 10.034
1 Mon-000102 100.18012 9.520860 12.296 12.223
2 Mon-000103 100.24811 9.586362 9.429 9.010
3 Mon-000104 100.26741 9.867225 11.811 11.797
4 Mon-000105 100.21005 9.814060 12.087 12.090
>>> df2.head()
Mon-id
0 Mon-000101
1 Mon-000121
2 Mon-000131
3 Mon-000141
4 Mon-000151
然后,我们可以在df2中重命名轴:
>>> df2.rename_axis({"Mon-id": "NAME"}).head()
NAME
0 Mon-000101
1 Mon-000121
2 Mon-000131
3 Mon-000141
4 Mon-000151
之后,merge
将做正确的事情:
>>> merged = df1.merge(df2.rename_axis({"Mon-id": "NAME"}))
>>> merged
NAME RA DEC Mean_I1 Mean_I2
0 Mon-000101 100.27242 9.608597 11.082 10.034
1 Mon-000121 100.45421 9.685027 11.805 11.777
2 Mon-000131 100.20533 9.397307 -100.000 11.764
3 Mon-000141 100.26134 9.388555 -100.000 12.571
最后,我们可以写出来,告诉它不要添加索引列:
>>> merged.to_csv("output.csv", index=False)
生成一个类似于
的文件NAME,RA,DEC,Mean_I1,Mean_I2
Mon-000101,100.27242,9.608597,11.082,10.034
Mon-000121,100.45421,9.685027,11.805,11.777
Mon-000131,100.20533,9.397307,-100.0,11.764
Mon-000141,100.26134,9.388555,-100.0,12.571
答案 3 :(得分:0)
解决此问题的一种方法(假设文件不是太大)将读入file1
并将数据存储为dict
,其中每一行都由索引键入(第一列) )和数据(剩余列)。然后阅读file2
作为键列表,然后您可以将其用作生成器,从file1
中的数据中提取匹配行。
快速而肮脏的解决方案:
#!/usr/bin/env python
DATA_FILE='file1.txt'
KEY_FILE='file2.txt'
# Read a list of keys to search for
keys = []
lineno = 1
for line in open(KEY_FILE):
if lineno > 1:
keys.append(line.strip())
lineno += 1
# Read data
data = {}
lineno = 1
for line in open(DATA_FILE):
if lineno > 1:
fields = line.split()
data[fields[0]] = fields[1:]
lineno += 1
# Extract data using keys
extracted_data = [[k, data[k]] for k in keys if k in data]
for k, v in extracted_data:
print k, ' '.join(v)
这可能是更有效的方法,但这可以完成工作,并允许您根据需要添加更多逻辑。
答案 4 :(得分:0)
由于文件可能很大,这种方法怎么样;它使用sqlite来处理文件操作:
import sqlite3
import csv
import os
conn = sqlite3.connect('temp.db')
c = conn.cursor()
c.execute('''CREATE TABLE master
(id text, ra text, dec text, mean1 text, mean2 text)''')
conn.commit() # Write changes
with open('master.csv') as f:
reader = csv.reader(f, delimiter=',')
next(reader) # skips header
for row in reader:
c.execute('INSERT INTO master VALUES (?,?,?,?,?)', row)
conn.commit()
with open('filter.txt') as f, open('diff.txt','w') as out:
writer = csv.writer(out, delimiter=',')
writer.writerow(('NAME','RA','DEC','Mean_I1','Mean_I2'))
for line in f:
c.execute('SELECT * FROM master WHERE id = ?',(line.strip(),))
row = c.fetchone()
if row:
writer.writerow(row)
conn.close()
os.remove('temp.db')
答案 5 :(得分:0)
在grep
上使用sed
和bash
。对于非常大的文件,这可能不是很有效。
grep -f <(sed 's/^/^/' file2.txt) file1.txt