【问题标题】:comparing two files and priniting lines with similar strings in one file [duplicate]比较两个文件并在一个文件中打印具有相似字符串的行[重复]
【发布时间】:2016-08-28 07:06:13
【问题描述】:

我有两个需要比较的文件,如果 file1 中的第一列与 file2 中的部分第一列匹配,则将它们并排添加到 file3 中,以下是示例:

文件1:

123123,ABC,2016-08-18,18:53:53
456456,ABC,2016-08-18,18:53:53
789789,ABC,2016-08-18,18:53:53
123123,ABC,2016-02-15,12:46:22

文件2

789789_TTT,567774,223452
123123_TTT,121212,343434
456456_TTT,323232,223344

输出:

123123,ABC,2016-08-18,18:53:53,123123_TTT,121212,343434
456456,ABC,2016-08-18,18:53:53,456456_TTT,323232,223344
789789,ABC,2016-08-18,18:53:53,789789_TTT,567774,223452
123123,ABC,2016-02-15,18:53:53,123123_TTT,121212,343434

谢谢..

【问题讨论】:

  • 是输出的最后一行应该是123123,ABC,2016-02-15,12:46:22,123123_TTT,121212,343434
  • 是的,因为文件 1 中的第 1 列与文件 2 中的第一个列匹配

标签: bash text compression


【解决方案1】:

使用 Gnu AWK:

$ awk -F, 'NR==FNR{a[gensub(/([^_]*)_.*/,"\\1","g",$1)]=$0;next} $1 in a{print $0","a[$1]}' file2 file1
123123,ABC,2016-08-18,18:53:53 123123_TTT,121212,343434
456456,ABC,2016-08-18,18:53:53 456456_TTT,323232,223344
789789,ABC,2016-08-18,18:53:53 789789_TTT,567774,223452
123123,ABC,2016-02-15,12:46:22 123123_TTT,121212,343434

解释:

NR==FNR {                                   # for the first file (file2)
    a[gensub(/([^_]*)_.*/,"\\1","g",$1)]=$0 # store to array
    next
} 
$1 in a {                                   # if the key from second file in array
    print $0","a[$1]                        # output
}

【讨论】:

  • 谢谢,但我在使用时遇到错误:awk -F, 'NR==FNR{a[gensub(/([^_]*)_.*/,"\\1","g",$1)]=$0;next} $1 in a{print $0","a[$1]}' file2.txt file1.txt awk: syntax error near line 1 awk: illegal statement near line 1 awk: syntax error near line 1 awk: bailing out near line 1
  • 这很奇怪。它在我的电脑上运行良好。你在使用 Gnu awk 吗?
【解决方案2】:

awk 解决方案将 file2 形成的键与 file1 的第 1 列相匹配 - 也应该在 Solaris 上使用 /usr/xpg4/bin/awk - 我冒昧地假设 OP 输出的最后一行有错字

file1=$1
file2=$2
AWK=awk
[[ $(uname) == SunOS ]] && AWK=/usr/xpg4/bin/awk
$AWK -F',' '
BEGIN{OFS=","}
# file2 key is part of $1 till underscore 
FNR==NR{key=substr($1,1,index($1,"_")-1); f2[key]=$0; next}
$1 in f2 {print $0, f2[$1]}
' $file2 $file1

测试

123123,ABC,2016-08-18,18:53:53,123123_TTT,121212,343434
456456,ABC,2016-08-18,18:53:53,456456_TTT,323232,223344
789789,ABC,2016-08-18,18:53:53,789789_TTT,567774,223452
123123,ABC,2016-02-15,12:46:22,123123_TTT,121212,343434

【讨论】:

  • 谢谢,但我在使用时遇到错误:
  • 错误是什么?
  • -bash-3.2# file1=$1 -bash-3.2# file2=$2 -bash-3.2# awk -F',' ' > BEGIN{OFS=","} > # file2 key is part of $1 till underscore > ARGIND==1{key=substr($1,1,index($1,"_")-1); f2[key]=$0; next} > $1 in f2 {print $0, f2[$1]} > ' $file2 $file1 awk: syntax error near line 5 awk: bailing out near line 5
  • 你在使用 gnu awk 吗? awk -V 说什么?
  • 我建议将代码放在一个文件中,然后使用两个文件名参数运行它
【解决方案3】:

纯 bash 解决方案

file1=$1
file2=$2
while IFS= read -r line; do
  key=${line%%_*}
  f2[key]=$line
done <$file2
while IFS= read -r line; do
  key=${line%%,*}
  [[ -n ${f2[key]} ]] || continue
  echo "$line,${f2[key]}"
done <$file1

【讨论】:

  • 这很好用,谢谢!!
猜你喜欢
  • 1970-01-01
  • 2013-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-14
  • 2017-07-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多