【问题标题】:I want to find the difference between 2 lists of comma dilimited text files我想找出 2 个逗号分隔的文本文件列表之间的区别
【发布时间】:2015-03-21 01:00:57
【问题描述】:

我有 2 个逗号分隔的文本文件。

文件 1 包含一个逗号分隔行

Brad@blah.com, jo@me.com.au, Josh@yahoo.co.uk

文件 2 包含一个逗号分隔行

George@here.com, brad@blah.com, sister@me.com.au, jo@me.com.au, josh@yahoo.co.uk

我想显示文件 2 中但不在文件 1 中的电子邮件地址,以便生成的文件 3 包含文本

George@here.com, sister@me.com.au

我一直在尝试使用 grep 找到解决方案,但任何 Windows 工具都可以。

【问题讨论】:

  • 如果是windows为什么要标记bash?
  • 两个文件都有单行?该文件可以包含多行吗?如果是,你会做什么过滤?每行?还是每个文件?还是什么?
  • Sorry JID 我想我会引诱一些可能有 grep 经验的 unix 用户。肯特 - 希望编辑澄清事情。
  • 鉴于地址来自人工输入,在某个地方,数据中会有大小写变化。您确实应该将所有内容都分解为小写,然后从那里开始使用您的解决方案。至于只有一行的文件 - 这很奇怪。如果您打算使用 Unix 解决方案,那么将文件转换为多行将使用普通命令行工具产生快速解决方案。

标签: file awk scripting cmd grep


【解决方案1】:

假设您有多个用逗号分隔的电子邮件地址,可选用空格和制表符包围,

awk -F'[ \t]*,[ \t]*' 'NR == FNR { for(i = 1; i <= NF; ++i) seen[tolower($i)] } NR != FNR { for(i = 1; i <= NF; ++i) { if(!(tolower($i) in seen)) { print $i } } }' file1 file2

awk 代码是

NR == FNR {                        # in the first file (overall line ==
                                   # line in file)
  for(i = 1; i <= NF; ++i) {       # for all fields in the line:
    seen[tolower($i)]              # remember that you saw it.
  }
}
NR != FNR {                        # in subsequent files (here the second)
  for(i = 1; i <= NF; ++i) {       # for all fields in the line:
    if(!(tolower($i) in seen)) {   # if you've not seen it before
      print $i                     # print it.
    }
  }
}

编辑:一个更简单的版本改编形式@JID的评论是

awk -v RS='\n|[ \t]*,[ \t\n]*' 'NR == FNR { seen[tolower($0)] } !(tolower($0) in seen)' file1 file2

JID 是正确的,使用记录分隔符可以使代码更简单——如果直接将文件拆分为电子邮件地址记录,则不需要 for 循环。我稍微更改了他的记录分隔符,以避免在尾随逗号和换行符之间引入空记录,并允许逗号前有空格。

这种简化的方法适用于mawkgawk,它们是当今最常见的awk。然而,正则表达式记录分隔符不是 POSIX 的一部分,所以这可能会在一些旧的 Unices 上中断。在这种情况下,请参考第一种非简化方法。这应该适用于任何地方——正则表达式字段分隔符符合 POSIX。

【讨论】:

  • 如果你使用 RS 而不是 FS,你可以减少一点 awk -vRS="\n|, *" 'NR==FNR{a[tolower($0)]++;next}!a[tolower($0)]'
  • 您应该声明使用多字符 RS 使其特定于 gawk(这很好,值得一提)。对于没有 gawk 的任何人,您可以改用 RS=,{ gsub(/^[[:space:]]+|[[:space:]]+$/,"") }
【解决方案2】:
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "file3line="
FOR /f "delims=" %%a IN (q28085343_file1.txt) DO (
 FOR /f "delims=" %%b IN (q28085343_file2.txt) DO (
  FOR %%s IN (%%b) DO (
   SET "found="
   FOR %%t IN (%%a) DO IF /i "%%s"=="%%t" SET found=Y
  IF NOT DEFINED found SET "file3line=%%s, !file3line!"
  )
 )
)
IF DEFINED file3line ECHO(%file3line:~0,-2%
GOTO :EOF

我使用了一个名为 q28085343_file1.txtq28085343_file2.txt 的文件,其中包含我的测试数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-02
    • 1970-01-01
    相关资源
    最近更新 更多