将两个文件与各自的字段进行比较,并以特定格式输出
Comparing two files with respective fields and output required in a specific format
我正在比较两个文件
food1.txt 文件并比较 food2.txt 文件,像这样
# cat food1.txt
pizza=1ea
chicken=5ea
tooboo=4ea
orange=2ea
# cat food2.txt
pizza=2ea
chicken=5ea
grape=3ea
tooboo=4ea
melon=1ea
- 我的作品...
FOOD1=`cat ./food1.txt`
FOOD2=`cat ./food2.txt`
echo "$FOOD1" | while read ACCOUNT
do
grep -w $ACCOUNT ./food2.txt >/dev/null 2>&1
if [ $? -eq 0 ] ; then
echo "-----[ OK ] : $ACCOUNT"
else
echo "-----[ WARN ] : $ACCOUNT"
fi
done
- 输出..但我不喜欢它
-----[ WARN ] : pizza=1ea
-----[ OK ] : chicken=5ea
-----[ OK ] : tooboo=4ea
-----[ WARN ] : orange=2ea
我要一起打印比较目标
- 我想要这样的输出
food2.txt food1.txt
pizza=2ea : [ NotMatch ] : pizza=1ea
: [ OK ] : chicken=5ea
: [ OK ] : tooboo=4ea
: [ NotExist ] : orange=2ea
grape=3ea : [ NotExist ] :
melon=1ea : [ NotExist ] :
可能吗?请帮助我。
使用您显示的示例,请尝试执行以下 awk
程序。在 GNU awk
.
中编写和测试
awk '
BEGIN{
FS="="
print ARGV[1]" "ARGV[2]
}
FNR==NR{
arr1[]=
next
}
( in arr1){
if(==arr1[]){
print " :[ OK ] : " [=10=]
}
else if(!=arr1[]){
print FS arr1[]" :[ NotMatch ] : "[=10=]
}
arr2[]
next
}
{
print [=10=]" :[ NotExist ] : "
}
END{
for(i in arr1){
if(!(i in arr2)){
print " :[ NotExist ] : "i FS arr1[i]
}
}
}
' food1.txt food2.txt
使用您展示的示例,以下将是 output:
food1.txt food2.txt
pizza=1ea :[ NotMatch ] : pizza=2ea
:[ OK ] : chicken=5ea
grape=3ea :[ NotExist ] :
:[ OK ] : tooboo=4ea
melon=1ea :[ NotExist ] :
:[ NotExist ] : orange=2ea
说明:为以上代码添加详细说明。
awk ' ##Starting awk program from here.
BEGIN{ ##Starting BEGIN section from here.
FS="=" ##Setting field separator as = here.
print ARGV[1]" "ARGV[2] ##Printing passed Input_file names here.
}
FNR==NR{ ##Checking condition FNR==NR which will be TRUE when food1.txt is being read.
arr1[]= ##Creating array named arr1 with index of 1st field and value is .
next ##next will skip all further statements from here.
}
( in arr1){ ##Checking condition if is present in arr1 then do following.
if(==arr1[]){ ##Checking condition if 2nd field is equal to arr1 value.
print " :[ OK ] : " [=12=] ##Printing ok message with current line of food2.txt here.
}
else if(!=arr1[]){ ##Else(in case 2nd field is NOT equal to arr1 value) then do following.
print FS arr1[]" :[ NotMatch ] : "[=12=] ##Printing first field FS value of arr1 followed by NotMatch followed by current line from food2.txt.
}
arr2[] ##Making an entry of current for arr2 array here.
next ##next will skip all further statements from here.
}
{
print [=12=]" :[ NotExist ] : " ##printing current line followed by NotExist statement.
}
END{ ##Starting END block for this program from here.
for(i in arr1){ ##Traversing through arr1 elements here.
if(!(i in arr2)){ ##Checking condition if key i is NOT present in arr2 then do following.
print " :[ NotExist ] : "i FS arr1[i] ##printing NOtExist statements followed by i FS and arr1 value.
}
}
}
' food1.txt food2.txt ##Mentioning Input_file names here.
由于标记了bash
,这里有一个使用关联数组的解决方案。第一个 while
循环填充读取第一个文件的数组。第二个 while
循环遍历第二个文件,检查键 and/or 值是否与数组中的条目匹配,然后删除它们。最后,for
循环遍历数组中剩余的“未检查”项。
out() {
if [[ -z "" ]]; then l="" m=" " r=""
elif [[ -z "" ]]; then l="=" m=": [ NotExist ] :" r=""
elif [[ -z "" ]]; then l="" m=": [ NotExist ] :" r="="
elif [[ "" == "" ]]; then l="" m=": [ OK ] :" r="="
else l="=" m=": [ NotMatch ] :" r="="; fi
printf '%-10s %s %-10s\n' "$l" "$m" "$r"
}
f1=food1.txt
f2=food2.txt
out "$f2" "$f1"
declare -A f
while IFS== read -r k v; do f[$k]=$v; done < "$f2"
while IFS== read -r k v; do out "${f[$k]}" "$v" "$k"; unset f[$k]; done < "$f1"
for k in "${!f[@]}"; do out "${f[$k]}" "" "$k"; done
food2.txt food1.txt
pizza=2ea : [ NotMatch ] : pizza=1ea
: [ OK ] : chicken=5ea
: [ OK ] : tooboo=4ea
: [ NotExist ] : orange=2ea
grape=3ea : [ NotExist ] :
melon=1ea : [ NotExist ] :
我正在比较两个文件
food1.txt 文件并比较 food2.txt 文件,像这样
# cat food1.txt
pizza=1ea
chicken=5ea
tooboo=4ea
orange=2ea
# cat food2.txt
pizza=2ea
chicken=5ea
grape=3ea
tooboo=4ea
melon=1ea
- 我的作品...
FOOD1=`cat ./food1.txt`
FOOD2=`cat ./food2.txt`
echo "$FOOD1" | while read ACCOUNT
do
grep -w $ACCOUNT ./food2.txt >/dev/null 2>&1
if [ $? -eq 0 ] ; then
echo "-----[ OK ] : $ACCOUNT"
else
echo "-----[ WARN ] : $ACCOUNT"
fi
done
- 输出..但我不喜欢它
-----[ WARN ] : pizza=1ea
-----[ OK ] : chicken=5ea
-----[ OK ] : tooboo=4ea
-----[ WARN ] : orange=2ea
我要一起打印比较目标
- 我想要这样的输出
food2.txt food1.txt
pizza=2ea : [ NotMatch ] : pizza=1ea
: [ OK ] : chicken=5ea
: [ OK ] : tooboo=4ea
: [ NotExist ] : orange=2ea
grape=3ea : [ NotExist ] :
melon=1ea : [ NotExist ] :
可能吗?请帮助我。
使用您显示的示例,请尝试执行以下 awk
程序。在 GNU awk
.
awk '
BEGIN{
FS="="
print ARGV[1]" "ARGV[2]
}
FNR==NR{
arr1[]=
next
}
( in arr1){
if(==arr1[]){
print " :[ OK ] : " [=10=]
}
else if(!=arr1[]){
print FS arr1[]" :[ NotMatch ] : "[=10=]
}
arr2[]
next
}
{
print [=10=]" :[ NotExist ] : "
}
END{
for(i in arr1){
if(!(i in arr2)){
print " :[ NotExist ] : "i FS arr1[i]
}
}
}
' food1.txt food2.txt
使用您展示的示例,以下将是 output:
food1.txt food2.txt
pizza=1ea :[ NotMatch ] : pizza=2ea
:[ OK ] : chicken=5ea
grape=3ea :[ NotExist ] :
:[ OK ] : tooboo=4ea
melon=1ea :[ NotExist ] :
:[ NotExist ] : orange=2ea
说明:为以上代码添加详细说明。
awk ' ##Starting awk program from here.
BEGIN{ ##Starting BEGIN section from here.
FS="=" ##Setting field separator as = here.
print ARGV[1]" "ARGV[2] ##Printing passed Input_file names here.
}
FNR==NR{ ##Checking condition FNR==NR which will be TRUE when food1.txt is being read.
arr1[]= ##Creating array named arr1 with index of 1st field and value is .
next ##next will skip all further statements from here.
}
( in arr1){ ##Checking condition if is present in arr1 then do following.
if(==arr1[]){ ##Checking condition if 2nd field is equal to arr1 value.
print " :[ OK ] : " [=12=] ##Printing ok message with current line of food2.txt here.
}
else if(!=arr1[]){ ##Else(in case 2nd field is NOT equal to arr1 value) then do following.
print FS arr1[]" :[ NotMatch ] : "[=12=] ##Printing first field FS value of arr1 followed by NotMatch followed by current line from food2.txt.
}
arr2[] ##Making an entry of current for arr2 array here.
next ##next will skip all further statements from here.
}
{
print [=12=]" :[ NotExist ] : " ##printing current line followed by NotExist statement.
}
END{ ##Starting END block for this program from here.
for(i in arr1){ ##Traversing through arr1 elements here.
if(!(i in arr2)){ ##Checking condition if key i is NOT present in arr2 then do following.
print " :[ NotExist ] : "i FS arr1[i] ##printing NOtExist statements followed by i FS and arr1 value.
}
}
}
' food1.txt food2.txt ##Mentioning Input_file names here.
由于标记了bash
,这里有一个使用关联数组的解决方案。第一个 while
循环填充读取第一个文件的数组。第二个 while
循环遍历第二个文件,检查键 and/or 值是否与数组中的条目匹配,然后删除它们。最后,for
循环遍历数组中剩余的“未检查”项。
out() {
if [[ -z "" ]]; then l="" m=" " r=""
elif [[ -z "" ]]; then l="=" m=": [ NotExist ] :" r=""
elif [[ -z "" ]]; then l="" m=": [ NotExist ] :" r="="
elif [[ "" == "" ]]; then l="" m=": [ OK ] :" r="="
else l="=" m=": [ NotMatch ] :" r="="; fi
printf '%-10s %s %-10s\n' "$l" "$m" "$r"
}
f1=food1.txt
f2=food2.txt
out "$f2" "$f1"
declare -A f
while IFS== read -r k v; do f[$k]=$v; done < "$f2"
while IFS== read -r k v; do out "${f[$k]}" "$v" "$k"; unset f[$k]; done < "$f1"
for k in "${!f[@]}"; do out "${f[$k]}" "" "$k"; done
food2.txt food1.txt
pizza=2ea : [ NotMatch ] : pizza=1ea
: [ OK ] : chicken=5ea
: [ OK ] : tooboo=4ea
: [ NotExist ] : orange=2ea
grape=3ea : [ NotExist ] :
melon=1ea : [ NotExist ] :