我遇到了这个问题并且我还没有解决它...我想操纵这些文件..如果file1的第一列与file2中的任何字符串匹配,则将其替换为file1的第二列。 ..然后崩溃它(我的意思是,我只需要每个字段的唯一值或"单元格"在output_file的第二列中)..
解决这个问题的方法并不重要(awk,perl,python)...文件包含100000行或更多...我一直在尝试单行awk脚本,但没有...
任何帮助表示赞赏。
此致
file1.txt
ID100000360640 ITEM1;ITEM2
ID100000360638 ITEM1;ITEM3
ID100000360644 ITEM1;ITEM4
ID100000363115 ITEM5;ITEM2;ITEM3
ID100000363116 ITEM1;ITEM7
ID100000382126 ITEM8;ITEM1
ID100000002165 ITEM1;ITEM2;ITEM3;ITEM9
ID100000002596 ITEM1;ITEM10
ID100000003084 ITEM1
file2.txt
ID200000000419 ID100000360638;ID100000360640;ID100000360644;ID100000394921
ID200000000938 ID100000363115;ID100000363116;ID100000363117;ID100000382126
ID200000001036 ID100000002165;ID100000398119
output_expected.txt
ID200000000419 ITEM1;ITEM3;ITEM1;ITEM2;ITEM1;ITEM4;ID100000394921
ID200000000938 ITEM5;ITEM2;ITEM3;ITEM1;ITEM7;ID100000363117;ITEM8;ITEM1;
ID200000001036 ITEM1;ITEM2;ITEM3;ITEM9;ID100000398119
processed_output.txt
ID200000000419 ITEM1;ITEM2;ITEM3;ITEM4;ID100000394921
ID200000000938 ITEM1;ITEM2;ITEM3;ITEM5;ITEM7;ITEM8;ID100000363117;
ID200000001036 ITEM1;ITEM2;ITEM3;ITEM9;ID100000398119
由于
答案 0 :(得分:1)
通过python3。
#!/usr/bin/python3
with open('file1.txt') as f, open('file2.txt') as r:
d = {}
m = f.read()
for line in m.split('\n'):
try:
d.update(dict([tuple(line.split())]))
except:
pass
j = r.read()
for k in d:
j = j.replace(k, d[k])
print(j)
<强>输出:强>
ID200000000419 ITEM1;ITEM3;ITEM1;ITEM2;ITEM1;ITEM4;ID100000394921
ID200000000938 ITEM5;ITEM2;ITEM3;ITEM1;ITEM7;ID100000363117;ITEM8;ITEM1
ID200000001036 ITEM1;ITEM2;ITEM3;ITEM9;ID100000398119
答案 1 :(得分:1)
这会产生折叠输出:
$ awk 'FNR==NR{a[$1]=$2;next} {c="";delete d;delete e;split($2, b, /;/);for (i in b)c=c";"(a[b[i]]?a[b[i]]:b[i]);split(substr(c,2),d,/;/); for(i in d)e[d[i]]=1; c=""; for (i in e){c=c";"i}; print $1,substr(c,2)}' file1.txt file2.txt
ID200000000419 ID100000394921;ITEM1;ITEM2;ITEM3;ITEM4
ID200000000938 ITEM1;ITEM2;ITEM3;ID100000363117;ITEM5;ITEM7;ITEM8
ID200000001036 ITEM1;ITEM2;ITEM3;ID100000398119;ITEM9
FNR==NR{a[$1]=$2;next}
当我们读取第一个文件时,会创建一个关联数组a
,它将第一个字段作为键关联,将第二个字段作为值关联。因此,a[ID100000360640]
的值为ITEM1;ITEM2
。这是针对file1.txt
的所有行完成的。 next
语句会导致跳过所有剩余的命令并跳转到下一行。
c="";delete d;delete e
如果我们来到这里,那意味着我们正在处理第二个文件file2.txt
。这三个命令为新行初始化变量c
和数组d
和e
。
split($2, b, /;/)
这会将第二个字段拆分为分号,并将结果分配给数组b
。
for (i in b)c=c";"(a[b[i]]?a[b[i]]:b[i])
这会创建未压缩的输出。
split(substr(c,2),d,/;/); for(i in d)e[d[i]]=1
这将创建一个关联数组e
,其键是未压缩输出中的每个字段。
c=""
在我们向其添加压缩输出之前,这会再次将c
初始化为空行。
for (i in e)c=c";"i
对于数组e
中的每个键,我们将键添加到字符串c
。这将创建压缩输出。
print $1,substr(c,2)
这将打印完整的压缩行。
答案 2 :(得分:1)
合理简短的awk方式
awk 'FNR==NR{a[$1]=$2;next}
{for(i in a)gsub(i,a[i])
x=split($2,b,";")
for(i=1;i<=x;i++)y!~b[i]";"&&y=y?y";"b[i]:b[i];$2=y;y=""}1' file file2
ID200000000419 ITEM1;ITEM3;ITEM2;ITEM4;ID100000394921
ID200000000938 ITEM5;ITEM2;ITEM3;ITEM1;ITEM7;ID100000363117;ITEM8
ID200000001036 ITEM1;ITEM2;ITEM3;ITEM9;ID100000398119
FNR==NR{a[$1]=$2;next}
当文件记录编号与总记录编号匹配时(实际上意味着在读取第一个文件时)使用第一个字段作为键将第二个字段分配给数组。Next
表示跳过所有进一步的指令并转到下一条记录。
for(i in a)gsub(i,a[i])
现在我们在第二个文件中作为FNR!= NR了
对于数组gsub
中的每个元素,将与键匹配的所有内容与数组中包含的内容进行交换。
x=split($2,b,";")
将第二个字段拆分为数组b,用;
分隔
将数组的大小指定为x。
for(i=1;i<=x;i++)
循环到数组的大小。
y!~b[i]";"&&
如果变量y已经包含b中的分割值,则不要继续。
y=y?y";"b[i]:b[i]
如果y存在则将b [i]中的值添加到结尾,否则只需将y设置为b [i]。
$2=y;y=""
将第二个字段设置为y(我们的新字符串)中的值,并将y重置为空。
https://www.gnu.org/software/gawk/manual/html_node/String-Functions.html