迭代txt文件并查找不在所有文件中的行

时间:2016-12-14 21:09:21

标签: shell powershell

我有3个文本文件的文件夹。 文件1,称之为test1.txt具有值

11
22
22

test2.txt具有值

11
22
22
33

test3.txt具有值

11
22
22
33
44
44

如何让我的最终结果等于(New.txt) 是:

44
44

这个值不在其他2个文件中,所以这就是我想要的。

到目前为止代码:

$result = "C:\NonDuplicate.txt"

$filesvalues=gci "C:\*.txt" | %{$filename=$_.Name; gc $_ | %{[pscustomobject]@{FileName= $filename; Row=$_ }}}

#list file where not exists others file with same value
$filesvalues | % {
                    $valtockeck=$_
                    [pscustomobject]@{
                                        Val=$valtockeck  
                                        Exist=$filesvalues.Where({ $_.FileName -ne $valtockeck.FileName -and $_.Row -eq $valtockeck.Row  }).Count -gt 0
                                     }  

                 } | 

                 where Exist -NE $true | 
                 % {$_.Val.Row | out-file $result -Append} 

这是错误:

Where-Object : Cannot bind parameter 'FilterScript'. Cannot convert the "Exist" value of type "System.String" to type "System.Management.Automation.ScriptBlock".
At line:16 char:23
+                  where <<<<  Exist -NE $true | 
    + CategoryInfo          : InvalidArgument: (:) [Where-Object], ParameterBindingException
    + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.WhereObjectCommand

5 个答案:

答案 0 :(得分:1)

    let shareAction = UITableViewRowAction(style: .normal, title: "Share") { (action: UITableViewRowAction, IndexPath) -> Void in

        let addTwitter = [UIActivityType.postToTwitter]


        let firstActivityItem = self.startups[indexPath.row]


        let activityViewController = UIActivityViewController(activityItems: [firstActivityItem,addTwitter], applicationActivities: nil)

        self.present(activityViewController, animated: true, completion: nil)


    }

答案 1 :(得分:1)

试试这个

#list files/values couple
$filesvalues=gci "C:\temp\test\test*.txt" -file | %{$filename=$_.Name; gc $_ | %{[pscustomobject]@{FileName= $filename; Row=$_ }}}

#list file where not exists others file with same value
$filesvalues | % {
                    $valtockeck=$_
                    [pscustomobject]@{
                                        Val=$valtockeck  
                                        Exist=$filesvalues.Where({ $_.FileName -ne $valtockeck.FileName -and $_.Row -eq $valtockeck.Row  }).Count -gt 0
                                     }  

                 } | 

                 where Exist -NE $true | 
                 % {$_.Val.Row | out-file "c:\temp\test\New.txt" -Append} 

答案 2 :(得分:1)

其他解决方案1 ​​

cyclic_index <- function(string1, string2) {

  ## gather info about the first string
  chars <- el(strsplit(string1, ""))
  length <- length(chars)
  vec <- seq_len(length)

  ## create a matrix of possible permutations
  permutations <- data.frame(matrix(NA, nrow = length, ncol = length + 1))
  names(permutations) <- c("id", paste0("index", vec))

  permutations$id <- vec

  ## calculate the offset indices
  for (r in vec)
    permutations[r, vec + 1] <- (vec + r - 1) %% (length)

  ## a %% a = 0 so reset this to a
  permutations[permutations == 0] <- length

  ## change from indices to characters
  permutations[ , vec + 1] <- sapply(vec, function(x) chars[unlist(permutations[x, vec + 1])])

  ## paste the characters back into strings
  permutations$string <- sapply(vec, function(x) paste0(permutations[x , vec + 1], collapse = ''))

  ## if string2 is a permutation of string1, return TRUE
  return(string2 %in% permutations$string)

}

cyclic_index("jonocarroll", "carrolljono")
#> TRUE

cyclic_index("jonocarroll", "callorrjono")
#> FALSE

cyclic_index("1234567", "4567123")
#> TRUE

答案 3 :(得分:1)

Compare-Object cmdlet的目的是比较两个输入组。
嵌套两个Compare-Object调用会产生所需的输出:

$file1Lines = Get-Content .\test1.txt
$file2Lines = Get-Content .\test2.txt
$file3Lines = Get-Content .\test3.txt

(Compare-Object `
  (Compare-Object -IncludeEqual $file1Lines $file2Lines).InputObject `
  $file3Lines |
    Where-Object SideIndicator -eq '=>'
).InputObject
  • Compare-Object输出[pscustomobject]个实例,其.InputObject属性包含输入对象,其.SideIndicator属性指示该值唯一的操作数 - {{1} }(LHS)或<=(RHS) - 以及>=,如果它包含在两个操作数(-IncludeEqual)中。

    < / LI> 第一次 ==调用中的
  • -IncludeEqual不仅会输出不同的行,还会包含 >是相同的,从而产生来自文件Compare-Objecttest1.txt的行的联合。

  • 通过指定第二次 test2.txt调用的开关,只有[包裹] 不同的行的对象输出(默认行为)。

  • 过滤Compare-Object然后将差异过滤到RHS独有的那些行。

将命令概括为N&gt; 3个文件并输出到新文件:

Where-Object SideIndicator -eq '=>'

请注意,# Get all input files as file objects. $files = Get-ChildItem .\test*.txt # I'll asume that all files but the last are the *reference files* - the # files for which the union of all their lines should be formed first... $refFiles = $files[0..$($files.count-2)] # ... and that the last file is the *difference file* - the file whose lines # to compare against the union of lines from the reference files. $diffFile = $files[($files.count-1)] # The output file path. $results = ".\New.txt" # Build the union of all lines from the reference files. $unionOfLines = @() $refFiles | ForEach-Object { $unionOfLines = (Compare-Object -IncludeEqual $unionOfLines (Get-Content $_)).InputObject } # Compare the union of lines to the difference file and # output only the lines unique to the difference file to the output file. (Compare-Object $unionOfLines (Get-Content $diffFile) | Where-Object SideIndicator -eq '=>').InputObject | Set-Content $results 默认使用Windows旧版单字节编码。使用Set-Content参数进行更改。

答案 4 :(得分:0)

好吧,不是将结果写在$ results文件中,而是将其保存在变量$ tmpResult中,然后对$ tmpResult和$ file3进行相同的检查以获得最终结果。如果您有超过3个文件,则可以创建一个循环来重复检查。

但上面的代码中缺少某些内容 - 您只获得file2中的唯一行而不是file1中的行。