首页 > 系统相关 >Linux awk、tr命令妙用,解析合并经纬度参数输出到终端窗口,方便一键复制

Linux awk、tr命令妙用,解析合并经纬度参数输出到终端窗口,方便一键复制

时间:2022-10-11 07:00:07浏览次数:84  
标签:22.706189 Linux tr lngandlat echo 参数 分隔符 awk 102.995824

场景概述

场景:很多时候我们从数据源(数据库、文本文件、Excel表格)等取到经纬度数据,需要拿到其他地方查询或者使用,各个平台需要的参数格式可能大不相同,比如有的平台需要经度+纬度的格式,有的地方需要纬度+经度的格式(eg:Google地图搜索),复制的文本携带的分隔符也五花八门,手动用记事本类的软件过滤亦可达到目的,但比较繁琐,不够快捷,平日在终端工作的情况下,可以借助Bash脚本实现一键过滤和组合后输出,直接选中复制即可(mintty窗口下还可以直接双击鼠标左键进行当前行整行复制!)

下文使用lngandlat函数实现同等目的,传递需要过滤和组合的经纬度参数即可;

优点:

  • 传递的参数先后顺序不敏感,代码一定程度对参数进行判别:哪一个是经度,哪一个是纬度;
  • 传递的参数格式较为宽松;分隔符数量不限,分隔符允许重叠,程序代码能对其进行智能缩减和过滤;
  • 允许参数前或参数后包含多余的分隔符,分隔符支持常见特殊字符,支持分隔符夹分隔符的特殊情况处理;
  • awk本身语法强大,允许后续增强和拓展其余功能;

借助tr、awk命令过滤分隔符,分隔字段域等

函数 lngandlat 实现代码:

lngandlat() {
	#经纬度格式转换,传入任意格式的经纬度数据,转换为需要的格式输出,方便一键复制
	#经纬度参数可以分开传递也可以合在一个参数传递(lngandlat 111,222 与 lngandlat 111 222效果相同);
	#支持 , # ;| ||  $ @ 等特殊符号作为经纬度分隔符,不限制分隔符字符数(重复无所谓),程序会自动缩减和处理
	# 参数中包含井号(#)和分号(;)时,参数需要用双引号或单引号包裹,其他情况下,引号可以省去
	# 注:awk没有内置求绝对值的函数,借用sqrt曲线救国;
	# See Also:https://zhidao.baidu.com/question/1801649363884678947.html
	# See Also2:https://zhidao.baidu.com/question/304949582658546204.html
	# eg:
	#	 lngandlat -102.995824 22.706189
	#	 lngandlat -102.995824,22.706189
	#    lngandlat 22.706189,-102.995824,
	#    lngandlat ";;102.995824##22.706189"
	#    lngandlat ";;-102.995824##22.706189"
	#------------------------------	
	_print_usage() { #打印帮助信息
		echo -e "lngandlat:\n\t纬度格式转换,传入任意格式的经纬度数据,转换为多种或许需要的格式输出;"
		echo -e "\t【目   的】:有的场景需要经度+纬度的组合,而有的需要纬度+经度组合,手动调换参数较为麻烦,故编写此快捷函数;"
		echo -e "\t【快捷操作】:输出数据后,mintty窗口下可以双击鼠标左键复制当前行文本;"
		echo -e "\t传入经纬度时先后顺序不敏感,分隔符可以为空格、逗号、#号或其他常见特殊字符,字符个数不限,程序会自动过滤处理;"
		echo -e "\t经纬度参数可以分开传递也可以合在一个参数传递(\`lngandlat 111,222\` 与 \`lngandlat 111 222\` 效果相同);"
		echo -e "\t注:参数数中包含井号(#)和分号(;)时,参数需要用双引号或单引号包裹,其他情况下,引号可以省去;"
		echo -e "\nUsage:\n\tlngandlat  *longitude~and~latitude~paramter\n"
		echo -e "--------------------------------------------------------------"
		echo -e "\nExample:\n\tlngandlat -102.995824 22.706189"
		echo -e "\tlngandlat 22.706189 -102.995824  #参数顺序不敏感,经度可前可后"
		echo -e "\tlngandlat -102.995824,22.706189  #两个参数可以合并传递"
		echo -e "\tlngandlat 22.706189,-102.995824"
		echo -e "\tlngandlat \"22.706189,,#,,-102.995824\"   #分隔符字数不限"
		echo -e "\tlngandlat \"-102.995824;22.706189\"  #参数包含分号需加引号"
		echo -e "\tlngandlat \"#102.995824##22.706189\"  #参数可以包含任意特殊字符作为经度和纬度的分隔符,且分隔符个数不限"
		echo -e "\tlngandlat \";;|\\\$-102.995824##22.706189\\$\\$\" #包含杂乱的分隔符不影响处理,注意包含\$需要转义"
		echo -e "\tlngandlat ';;|\$-102.995824##22.706189\$\$' #使用单引号无需转义\$"
	}
	[ $# -eq 0 ] && echo -e "缺少参数!"
	if [[ $# == 0 || "${*,,}" == "-h" || "${*,,}" == "--help" ]];then	
		_print_usage && return
	fi
	
	#这里借助awk统一在位置1输出经度,位置2输出纬度:
	mapfile -t Coords <<<$(\
		echo "$*"|tr -s ',;#|@$ '|awk -F '[,#;\\|\\$@ ]' '{
			sub(/[^0-9]+?$/,""); /*替换参数结尾的分隔符,否则会影响栏位$NF定位*/
			/*依次向前取到倒数第二个非空字段*/
			/*为了处理分隔符夹分隔符的情况:lngandlat "22.706189,,#,,-102.995824"*/
			findex=NF-1;
			while($findex==""){
				findex=findex-1;
			}
			previous=$findex;
			if(previous<0 && $NF<90){ /*第一个数字小于零,第二个数字小于90,则认定为 经度、纬度格式*/ 
				print previous;
				print $NF;
			}else if($NF<0 && previous<90) { /*第二个数字小于零,第一个数字小于90,则认定为 纬度、经度格式*/ 
				print $NF;
				print previous;
			}else if(sqrt(previous*previous)>65 && sqrt($NF*$NF)>65) { /*两个数字绝对值过大,则认定为错误的经纬度数据(纬度最高为冰岛国的雷克雅未克:64°09′)*/ 
				print "ERROR";
				print "ERROR";
			}else if(sqrt(previous*previous)<65 && sqrt($NF*$NF)>90) { /*对一个参数和第二个参数模糊求绝对值,推测为 纬度、经度格式*/ 
				print $NF;
				print previous;
			}else if(sqrt($NF*$NF)<65) { /*对二个参数模糊求绝对值,默认情况认定为 经度、纬度格式*/ 
				print previous;
				print $NF;
			}
		/*此处不屏蔽错误,保留awk命令原始错误输出结果到屏幕终端,以便于查找原因!*/
		/*复现报错提示可以使用:lngandlat "" */
		}' 2>/dev/tty||echo -e "\033[41;37m输入数据解析有错误,请检查参数!\033[0m" >/dev/tty
	)

	[[ "${Coords[@]}" == "" ]] && return #有错误则直接退出!
	
	local lng="${Coords[0]}" #经度
	local lat="${Coords[1]}" #纬度
	
	printf "原始数据:\n经度:%s\n纬度:%s\n\n" "$lng" "$lat"
	printf "经纬度:\n%s,%s\n\n" $lng $lat
	printf "纬经度:\n%s,%s\n\n" $lat $lng
	#jq命令存在则同时输出格式化的JSON数据:
	[ ! -z $(type -t jq) ] && printf '{"lng":"%s","lat":"%s"}' $lng $lat|jq '.'
}

使用帮助截图:

使用效果截图:

处理复杂分隔符的情况:

Gitee代码共享:

https://gitee.com/hexiyou/shell-scripts/blob/master/lngandlat.sh

标签:22.706189,Linux,tr,lngandlat,echo,参数,分隔符,awk,102.995824
From: https://www.cnblogs.com/cnhack/p/16777980.html

相关文章

  • 关于树上启发式合并(dsu on tree)
    引入题目地址题目大意:给一棵\(N\)个点、有边权的树,求最小的不小于k的一条树上路径的长度。我的第一想法肯定是把每个节点的的信息不断像上传,同时还在这个节点的位置处......
  • Linux
    ls:查询​ -a​ -lpwd:当前位置mkdir:创建文件夹touch:创建文件cp:复制文件cp源文件目标文件cpa.txt/home/admin/a.txtmv:移动rm:删除rma.txtrma-rrm*-r......
  • 点击运行bat文件的时候报错:关于findstr不是内部或外部命令也不是可运行的程序或批处理
    一开始搜索说这是PATH环境的问题,在path中追加:%SystemRoot%\system32;%SystemRoot%;()其中‘\’如果用'/'还会报错 但是这个方法没用,运行bat时候还是显示关于findstr不是......
  • 为什么要分为service层,dao层,controller层?
        开发中有感而想,然后查了一下,发现这个观点不错,以后开发尽量业务代码还是写在service层,然后controller层简单点,看起来也清晰。首先,分三层并不仅仅是java的......
  • linux sed 命令详解
     sed 常用选项 和 常用命令 sed是一个很好的文件处理工具,本身是一个管道命令,主要是 以行为单位 进行处理,可以将数据行进行替换、删除、新增、选取等特定工作。  s......
  • linux wc命令参数及用法详解
    Linux系统提供了wc命令来统计文件的行数统计当前目录下的所有文件行数:wc-l*当前目录以及子目录的所有文件行数:find .*|xargswc-l可以把*改成所要匹配的文件,例如Jav......
  • linux 之间 copy 传输文件方法:ftp、samba、sftp、scp、sz/rz
     不同的Linux之间copy文件通常有4种方法1.ftp2.samba服务3.sftp4.scp前三种方法都比较繁琐,最简单的方法就是scp  scpscp本地用户名@IP地址:文件名1远程用户名@IP......
  • Linux 文件 IO
    参考APUE整理。如有疑问,可以直接看APUE。。。  linux文件IOIO文件操作时最常用的也最基本的内容。linux文件系统是由两层结构构建:第一层是虚拟文件系统(VFS),第二层是......
  • sizeof与strlen的区别
    1、sizeof是一个关键字,而strlen确实一个函数。2、sizeof求的是字节长度,而strlen求的却是实际长度。比如inta=1;sizeof(a)==4而strlen(a)=13、sizeof求的是分配......
  • Linux安装配置类似mac下的docky
    百度经验:​​ubuntu安装配置类似mac下的docky​​亲手打造自己的Linux桌面环境:​​http://os.51cto.com/art/201510/493896_all.htm​​Dock是一种图形用户界面元素,允许用户......