所以我想说我有5个文件:f1,f2,f3,f4,f5。如何从所有5个文件中删除公共字符串(所有文件中的相同文本)并将它们放入第6个文件f6?请告诉我。
文件格式:
property.a.p1=some string
property.b.p2=some string2
.
.
.
property.zzz.p4=123455
因此,如果以上是文件1的摘录而文件2到5中也包含字符串 property.a.p1=some string
,那么我想将文件1中的字符串删除5并将其放入文件6.每个文件的每一行都在一个新行上。因此,我将逐个比较换行符上的每个字符串。每个文件大约有400到600行。
我在一个论坛上发现了这个问题,用于使用ruby从两个文件中删除常用字符串:
$ ruby -ne 'BEGIN {a=File.read("file1").split(/\n+/)}; print $_ if a.include?($_.chomp)' file2
答案 0 :(得分:2)
看看这是否符合您的要求。这是一个“2遍”解决方案,第一遍使用哈希表来查找公共行,第二遍使用它来过滤掉与公共匹配的任何行。
$files = gci "file1.txt","file2.txt","file3.txt","file4.txt","file5.txt"
$hash = @{}
$common = new-object system.collections.arraylist
foreach ($file in $files) {
get-content $file | foreach {
$hash[$_] ++
}
}
$hash.keys |% {
if ($hash[$_] -eq 5){[void]$common.add($_)}
}
$common | out-file common.txt
[regex]$common_regex = ‘^(‘ + (($common |foreach {[regex]::escape($_)}) –join “|”) + ‘)$’
foreach ($file in $files) {
$new_file = get-content $file |? {$_ -notmatch $common_regex}
$new_file | out-file "new_$($file.name)"
}
答案 1 :(得分:0)
在SQL数据库中创建一个表,如下所示:
create table properties (
file_name varchar(100) not null, -- Or whatever sizes make sense
prop_name varchar(100) not null,
prop_value varchar(100) not null
)
然后用一些简单的正则表达式甚至只用split
解析你的文件:
prop_name, prop_value = line.strip.split('=')
将解析后的数据转储到您的表中,然后执行一些SQL来查找所有文件通用的属性:
select prop_name, prop_value
from properties
group by prop_name, prop_value
having count(*) = $n
其中$n
被输入文件的数量替换。现在您有一个所有常见属性及其值的列表,所以将它们写入新文件,从properties
表中删除它们,然后旋转properties
中剩下的所有行并写入它们到适当的文件(即file_name
列命名的文件)。
你说这些文件是“巨大的”,所以你可能不希望同时将所有这些文件粘贴到内存中。您可以执行多次传递并使用磁盘上的哈希库来跟踪已经看到的内容以及在哪里,但如果您有一个SQL数据库并且每个人都应该至少在SQLite中徘徊,这将浪费时间。管理大量结构化数据是SQL和数据库的用途。