Regex 打印匹配和非匹配图案

Regex 打印匹配和非匹配图案,regex,bash,unix,awk,grep,Regex,Bash,Unix,Awk,Grep,我试图比较两个文件,然后在匹配时返回其中一个文件列。我现在使用的代码不包括不匹配的模式,而只是打印出匹配的模式。我需要使用grep打印所有匹配和不匹配的结果 文件1: A,42.4,-72.2 B,47.2,-75.9 Z,38.3,-70.7 C,41.7,-95.2 F A B Z C P E A,42.4,-72.2 B,47.2,-75.9 Z,38.3,-70.7 C,41.7,-95.2 F A,42.4,-72.2 B,47.2,-75.9 Z,38.3,-70.7 C,41

我试图比较两个文件,然后在匹配时返回其中一个文件列。我现在使用的代码不包括不匹配的模式,而只是打印出匹配的模式。我需要使用
grep
打印所有匹配和不匹配的结果

文件1:

A,42.4,-72.2
B,47.2,-75.9
Z,38.3,-70.7
C,41.7,-95.2
F
A
B
Z
C
P
E
A,42.4,-72.2
B,47.2,-75.9
Z,38.3,-70.7
C,41.7,-95.2
F
A,42.4,-72.2
B,47.2,-75.9
Z,38.3,-70.7
C,41.7,-95.2
P
E
while IFS=',' read point lat lon; do

check=`grep "${point} /home/aaron/file2 | awk '{print $1}'`

echo "${check},${lat},${lon}"

done < /home/aaron/file1
文件2:

A,42.4,-72.2
B,47.2,-75.9
Z,38.3,-70.7
C,41.7,-95.2
F
A
B
Z
C
P
E
A,42.4,-72.2
B,47.2,-75.9
Z,38.3,-70.7
C,41.7,-95.2
F
A,42.4,-72.2
B,47.2,-75.9
Z,38.3,-70.7
C,41.7,-95.2
P
E
while IFS=',' read point lat lon; do

check=`grep "${point} /home/aaron/file2 | awk '{print $1}'`

echo "${check},${lat},${lon}"

done < /home/aaron/file1
当前结果:

A,42.4,-72.2
B,47.2,-75.9
Z,38.3,-70.7
C,41.7,-95.2
F
A
B
Z
C
P
E
A,42.4,-72.2
B,47.2,-75.9
Z,38.3,-70.7
C,41.7,-95.2
F
A,42.4,-72.2
B,47.2,-75.9
Z,38.3,-70.7
C,41.7,-95.2
P
E
while IFS=',' read point lat lon; do

check=`grep "${point} /home/aaron/file2 | awk '{print $1}'`

echo "${check},${lat},${lon}"

done < /home/aaron/file1
预期结果:

A,42.4,-72.2
B,47.2,-75.9
Z,38.3,-70.7
C,41.7,-95.2
F
A
B
Z
C
P
E
A,42.4,-72.2
B,47.2,-75.9
Z,38.3,-70.7
C,41.7,-95.2
F
A,42.4,-72.2
B,47.2,-75.9
Z,38.3,-70.7
C,41.7,-95.2
P
E
while IFS=',' read point lat lon; do

check=`grep "${point} /home/aaron/file2 | awk '{print $1}'`

echo "${check},${lat},${lon}"

done < /home/aaron/file1
Bash代码:

A,42.4,-72.2
B,47.2,-75.9
Z,38.3,-70.7
C,41.7,-95.2
F
A
B
Z
C
P
E
A,42.4,-72.2
B,47.2,-75.9
Z,38.3,-70.7
C,41.7,-95.2
F
A,42.4,-72.2
B,47.2,-75.9
Z,38.3,-70.7
C,41.7,-95.2
P
E
while IFS=',' read point lat lon; do

check=`grep "${point} /home/aaron/file2 | awk '{print $1}'`

echo "${check},${lat},${lon}"

done < /home/aaron/file1
当IFS=','读取点横向;做
check=`grep“${point}/home/aron/file2 | awk'{print$1}'`
回显“${check},${lat},${lon}”
完成在awk中:

$ awk -F, 'NR==FNR{a[$1]=$0;next}{print ($1 in a?a[$1]:$1)}' file1 file2
F
A,42.4,-72.2
B,47.2,-75.9
Z,38.3,-70.7
C,41.7,-95.2
P
E
解释:

$ awk -F, '                  # field separator to ,
NR==FNR {                    # file1
    a[$1]=$0                 # hash record to a, use field 1 as key
    next
}
{
    print ($1 in a?a[$1]:$1) # print match if found, else nonmatch
}
' file1 file2

如果您不关心顺序,GNU coreutils中有一个
join
二进制文件,它正好满足您的需要:

$sort file1 > sortedFile1
$sort file2 > sortedFile2
$join -t, -a 2 sortedFile1 sortedFile2
A,42.4,-72.2
B,47.2,-75.9
C,41.7,-95.2
E
F
P
Z,38.3,-70.7
它依赖于正在排序的文件,否则将无法工作


现在请您离开我的
/home/

另一个
加入基于
的解决方案,以保持秩序

f() { nl -nln -s, -w1 "$1" | sort -t, -k2; }; join -t, -j2 -a2 <(f file1) <(f file2) | 
sort -t, -k2 | 
cut -d, -f2 --complement

F
A,42.4,-72.2,2
B,47.2,-75.9,3
Z,38.3,-70.7,4
C,41.7,-95.2,5
P
E

f(){nl-nln-s,-w1“$1”| sort-t,-k2;};加入-t,-j2-a2当前解决方案的问题:
1
。您在
grep“${point}/home/亚伦/file2
中缺少一个双引号
2
。您应该从另一个文件开始打印该文件中的所有行

while IFS=',' read point; do
   echo "${point}$(grep "${point}" /home/aaron/file1 | sed 's/[^,]*,/,/')"
done < /home/aaron/file2
4
。使用
是错误的方法。
对于小文件,它可以完成工作,但是你会被大文件卡住。原因是您将为文件2中的每一行调用
grep
,多次读取文件1。
最好使用awk或其他解决方案。 另一种解决方案是使用另一个
sed
命令输出的
sed

sed -r 's#([^,]*),(.*)#s/^\1$/\1,\2/#' /home/aaron/file1
这将为第二个
sed
发出命令

sed -f <(sed -r 's#([^,]*),(.*)#s/^\1$/\1,\2/#' /home/aaron/file1) /home/aaron/file2

sed-f如果文件1中的一行在文件2中没有第一列值,该怎么办?