Awk 比较两个文件的第一个字段,如果字段匹配,则输出两个文件的这些字段的整个记录

Awk 比较两个文件的第一个字段,如果字段匹配,则输出两个文件的这些字段的整个记录,awk,field,matching,Awk,Field,Matching,我有两个文件,par1.txt,par2.txt。我想查看两个文件的第一个字段或列,比较它们,然后如果它们匹配,则打印匹配的记录或行 示例文件: par1.txt ocean;stuff about an ocean;definitions of oeans park;stuff about parks;definitions of parks ham;stuff about ham;definitions of ham par2.txt hand,stuff about hands,defi

我有两个文件,par1.txt,par2.txt。我想查看两个文件的第一个字段或列,比较它们,然后如果它们匹配,则打印匹配的记录或行

示例文件:

par1.txt

ocean;stuff about an ocean;definitions of oeans
park;stuff about parks;definitions of parks
ham;stuff about ham;definitions of ham
par2.txt

hand,stuff about hands,definitions of hands
bread,stuff about bread,definitions of bread
ocean,different stuff about an ocean,difference definitions of oceans
ham,different stuff about ham,different definitions of ham
至于我的输出,我想要的是

ocean:stuff about an ocean:definitions of oeans
ocean:different stuff about an ocean:difference definitions of oceans
ham:different stuff about ham:different definitions of ham
ham:stuff about ham:definitions of ham
文件中的FS不同,如示例所示。
输出FS不必是“:”它不能是一个空格

使用
awk

awk -v OFS=":" '
{ $1 = $1 }
NR==FNR { lines[$1] = $0; next }
($1 in lines) { print lines[$1] RS $0 }
' FS=";" par1.txt FS="," par2.txt
输出:

ocean:stuff about an ocean:definitions of oeans
ocean:different stuff about an ocean:difference definitions of oceans
ham:stuff about ham:definitions of ham
ham:different stuff about ham:different definitions of ham
说明:

ocean:stuff about an ocean:definitions of oeans
ocean:different stuff about an ocean:difference definitions of oceans
ham:stuff about ham:definitions of ham
ham:different stuff about ham:different definitions of ham
  • 将输出字段分隔符设置为
    。如果要分隔空间,则不需要设置
    -v of s
  • $1=$1
    帮助我们重新设置整行的格式,以便在重新构造时可以获取OFS的值
  • NR==FNR
    读取数组中的第一个文件
  • 当我们处理第二个文件时,我们在数组中查找第一列。如果存在,则打印数组中的行和第二个文件中的行
  • FS=“;”par1.txt FS=“,”par2.txt
    是一种可以为不同文件指定不同字段分隔符的技术

如果两个文件中都有Repeative第一列,并且希望捕获所有内容,那么请使用以下命令。这是类似的逻辑,但我们将所有行保留在数组中,并在最后打印

awk -v OFS=":" '
  { $1 = $1 }
  NR==FNR {
      lines[$1] = (lines[$1] ? lines[$1] RS $0 : $0);
      next
  }
  ($1 in lines) {
      lines[$1] = lines[$1] RS $0;
      seen[$1]++
  }
  END { for (patt in seen) print lines[patt] }
' FS=";" par1.txt FS="," par2.txt

编辑的答案

根据您的评论,我相信您有2个以上的文件,这些文件有时使用逗号,有时使用分号作为分隔符,并且您希望打印任何数量的具有匹配第一个字段的行,只要有多个与该第一个字段匹配。如果是这样的话,我想你想要这个:

awk -F, '
   {
     gsub(/;/,",");$0=$0;              # Replace ";" with "," and reparse line using new field sep
     sep="";                           # Preset record separator to blank
     if(counts[$1]++) sep="\n";        # Add newline if anything already stored in records[$1]
     records[$1] = records[$1] sep $0; # Append this record to other records with same key
   }
   END { for (x in counts) if (counts[x]>1) print records[x] }' par*.txt
原始答案

我想到了这个:

awk -F';' '
   FNR==NR {x[$1]=$0; next}
   $1 in x {printf "%s\n%s\n",$0,x[$1]}' par1.txt  <(sed 's/,/;/' par2.txt)
awk-F';“”
FNR==NR{x[$1]=$0;next}

$1在x{printf”%s\n%s\n“,$0,x[$1]}”par1.txt中我认为行的顺序不保证,因此
ocean
可能出现在
par1.txt
par2.txt
中的任何地方?是的,这是正确的。谢谢,这非常有效!只有一个问题,如果说,我想一次处理两个以上的文件,该怎么办?首先使用
cat
将文件连接在一起,即
cat file6 file7 file8 file9>bigfile,然后使用
bigfile`作为
awk
的第二个输入。嗯,它似乎只将记录分为两组输出。这是因为问题说最初有两个文件,所以它存储第一个文件中的所有记录,然后,由于每个记录都是从第二个文件读取的,它检查是否已经存储了定义,如果已经存储了定义,则同时打印这两个定义。也许您需要重述这个问题,以处理一个包含所有文件的文件,这些文件作为单个输入文件连接在一起?我也不确定这是否是你想要的。也许你不同的字段分隔符和文件数量都会分散你的注意力。假设您实际拥有文件
par1.txt
par2.txt
par37.txt
。如果您执行
tr';'',big.txt
,您现在可以说需要对
big.txt
做些什么吗?+1!如果愿意,可以将
$1=$1
移动到脚本前面的公共块<代码>awk-v OFS=':''{$1=$1}NR==FNR{a[$1]=$0;下一个}$1在{打印a[$1]或$0}'FS=';'file1 FS=','file2