我有一个CSV文件,格式如下:
0001 @ word @ some information @ other information @
最后一列留空。我想标记每一行并将标记放在最后一列。
我还有一个目录,其中包含纯文本文件,其中只包含单词列表(每行1个)。每个列表的文件名与我想要应用的标签相同。
列表/ 列表/ fruit1 列表/ fruit2 列表/ vegetables1 列表/ vegetables2
如何将包含CSV第2列中单词的完全匹配的每个文件的名称添加到CSV的结尾?例如:
CSV中的一行是这样的,“香蕉”一词出现在fruit1
和fruit2
的两个列表中。
0004 @ banana @ some information @ other information @
上面的行会将这两个文件名添加到CSV的最后一列:
0004 @ banana @ some information @ other information @ fruit1 fruit2
答案 0 :(得分:1)
如果单词文件适合内存,一个解决方案就是读取所有单词的内容并将它们映射到字典,其中键是要应用的标记,值是这些标记的单词集:
tags = {}
for filename in filenames:
with open(filename) as f:
tags[filename] = {line.strip() for line in f}
之后,可以读取输入的csv文件,并且对于每一行,可以检查单词列以验证它是否包含在任何标记中,如果是这种情况,则将标记添加到所需的列。创建标记列后,如果将结果写入包含与新标记列相同的数据的输出csv文件,则结果为:
import csv
word_column_number = 1
tags_column_number = 4
reader = csv.reader(open(input_csv), delimiter='@')
writer = csv.writer(open(output_csv, 'w'), delimiter='@')
for row in reader:
word_column = row[word_column_number].strip()
tag_column = [name for name, words in tags.iteritems()
if word_column in words]
row[tags_column_number] = ' {0}'.format(' '.join(tag_column))
writer.writerow(row)
答案 1 :(得分:1)
您可以使用循环读取每一行。使用cut
提取第二个字段,然后使用grep
查找包含此字段的文件。然后echo
结果。
如下所示:
while read line
do
word=$(cut -d@ -f2 <<< "$line")
results=( $(grep -l $word Lists/*) )
echo "$line ${results[@]##*/}"
done < input.txt
答案 2 :(得分:1)
这会从Lists /中的文件创建一个sed
脚本,并在csv文件上运行它:
(cd ./Lists;
for file in * ; do
sed 's%^%/^[^@]*@ %;
s%$% @/s/$/ '$file'/%' $file
done) | sed -f- file.csv