我需要将一些 GPS 坐标转换为特定格式,这些坐标是图片的 exif 信息的输出。
这是典型的输出:
exif:GPSLatitude: 10/1, 10/1, 10/1
exif:GPSLatitudeRef: N
exif:GPSLongitude: 10/1, 10/1, 10/1
exif:GPSLongitudeRef: E
这是我需要获取的字符串:
10 10 10N 10 10 10E
我已经能够使用以下脚本来做到这一点:
cat $somefile | sed "s/ /$nul/g" | sed "s/exif:GPSLatitudeRef: /$nul/g" | sed "s/exif:GPSLongitude:/$nul/g" | sed "s/exif:GPSLongitudeRef: /$nul/g" | sed "s/exif:GPSLatitude: /$nul/g" | sed "s/\/1/$nul/g" | sed "s/,/$nul/g" | tr -d '\n'
然而我意识到有些图片的输出略有不同,如下所示:
exif:GPSLatitude: 10/1, 10/1, 1099/100
exif:GPSLatitudeRef: N
exif:GPSLongitude: 10/1, 10/1, 1088/100
exif:GPSLongitudeRef: E
我知道/1
、/10
和/100
(也许/1000
也是 a)是前面数字的分母。
考虑到以下因素:
- 我不需要很高的精度,因此我可以放弃最后一个数字的最后两位小数(即:
1088/100
可以变成10
而不是10.88
); - 我希望有这样的准确性;
- 我不完全确定坐标的前两个数字(度和分,即
10/1 10/1
:)也可以有小数。在这种情况下,指向世界上不同地方的坐标精度将完全混乱。
我怎样才能修改该脚本(也许让它更优雅一点)来进行计算并实际上用一个数字代替一个分数?
答案1
执行此操作非常复杂sed
。更合适的工具是awk
或bc
。例如,要使用bc
add anothersed
将输入转换为由“;”分隔的表达式 (10/1) 和字符串 (" ") 序列。或换行符导致 bc 输入以下内容:
10/1;" "; 10/1;" "; 1099/100
"N \n"
10/1;" "; 10/1;" "; 1088/100
"E \n"
bc
将评估每个表达式,输出将10.00 10.00 10.99N 10.00 10.00 10.88E
如您所愿。这是您需要的 sed|bc|tr:
sed '1i\
scale=2
/Ref: /s/.$/"& \n"/
s/.*: //
s/,/;" ";/g
' |
bc | tr -d '\n'
或者,您可以使用以下命令awk
替换所有sed
和命令:tr
awk '
NF==4 { for(i=2;i<=4;i++){
split($i,x,"/")
printf "%s%g",i==2?"":" ",x[1]/x[2]
}
}
NF==2 { printf "%s%s",$2,$1~/Lat/?" ":"\n" }'
这将查找具有 4 个字段(由空格分隔)的行,并且对于字段 2 到 4,将字段 $i(例如“1099/100”)在“/”字符处分成两部分。然后,它使用%g
数字的通用格式打印第 1 部分除以第 2 部分 (x[1]/x[2]) 。对于字段 2 %s
, 中的不printf
被任何内容替换,而对于其他 2 个字段,则被替换为空格。这会分隔输出中的数字。
对于具有 2 个字段 (NF==2) 的行,它会打印第二个字段 ( $2
),如果字段 1 包含模式“Lat”,它会打印一个空格,否则打印一个换行符。