shell私房菜part2

本文通过实战案例介绍如何使用Shell脚本进行文件处理,包括利用split命令分割文件、使用for循环批量重命名文件等内容。

shell私房菜part1传送门

shell私房菜part3 传送门

命令行是键盘屏幕出来以后,图形界面风靡之前,主流的人机交的渠道方式,现下用惯图形界面的同学估计要吐槽它的单调素颜。

 

但是它还是具有强大的生命力,因为它存在的时间够长,被n多的大牛把玩过打磨过,它是精巧高效的工具,当然学习曲线显得陡峭。我是金庸迷,在我看来,这东西有点“重剑无锋,大巧不工”的范儿。

 

我们来瞻仰一下Unix系统上管道机制的发明者,也是Unix文化的缔造者之一的Douglas McIlroy大牛的哲学

1.       程序应该只关注一个目标,并尽可能把它做好。I love KISSkeep it simple stupid

2.       让程序能够互相协同工作。(都来用俺发明的管道吧)

3.       应该让程序处理文本数据流,因为这是一个通用的接口(管道要高效,那就让它内里流动最简单的东西吧)

 

如果我们回顾上一个part最后写成的shell命令行

cat abcd.csv |grep -v location|sed -e 's:"::g'|sed -e 's:\s::g'|awk -F',' '{print "update tkm_cinema set latitude='\''"$2"'\'',longitude=\047"$3"\047 where id="$1";"}'  > test.sql

分开来看,cat,grep,sed,|管道,>输出重定位符,它们都是符合第一条的,KISS。awk是个逆天的东西。

它们的输入输出都是文本数据流,符合第三条。

使用管道串接,协同完成了一个任务,这是第二条。


 Ok,复习完毕,开始今天的新内容:循环,条件,变量。和昨天一样

红色字是命令行啊(在括号里的绿色的字是注释啊)浅蓝色字是屏幕输出啊。

 还是上实战案例

Case:我手里有一份IOS设备tokenlist文件,每行一个,数量有17k+,需要切割成1000行一个小文件,并且以特定的文件后缀名“custom.txt”结尾。

 

像切割文件这种事,一定是被解决过有工具的,可能还很多,我恰好知道一个叫split,但是参数记不得了,于是先man一下,man是shell的帮助文档工具哦,常用的命令工具都能找到,比度娘快哦,当然基本都是鸟文写的。

man splitman是手册单词的简写哦,女程序员如果觉得不爽要用woman我也能教个方法给你,^_^, man后面跟你想要了解的命令名就好,进入man的界面,q是退出,gg到文档头部,G到文档尾部,/xxxx可以搜索xxxx字符串(搜索后,n跳到下一个命中xxxx的地方),世上本没有shell熟手,man看的多也便成了熟手,split简单的,不到两屏幕的鸟文,很快就后就看到需要用到的参数了,用-l参数,定义按多少行分割文件,用PREFIX可以自定前缀,)

split [OPTION] [INPUT [PREFIX]]

-l, --lines=NUMBER

put NUMBER lines per output file

 

搞清楚split用法就来分割文件吧。

split -l 1000 token.list pushList(对照split [OPTION] [INPUT [PREFIX]]看,OPTION那里是-l 1000,表示按每1000行一个文件;INPUT那里是token.list,表示待分割输入文件;PREFIXpushList,表示希望的分割出来的文件的前缀)

 

看看分割出来的结果,

ls -lls,显示文件列表命令,常用到令人发指的程度,有n多的参数可选,强烈建议大家man一下,重点关注下-r –S –t -h

-rw-r--r-- 1 mengchang users  184664 Nov 14 09:43 token.list

-rw-r--r-- 1 mengchang users   10587 Nov 15 11:08 pushListaa

-rw-r--r-- 1 mengchang users   10845 Nov 15 11:08 pushListab

。。。。。。

-rw-r--r-- 1 mengchang users    3035 Nov 15 11:08 pushListar

 

看看每个文件的行数是否是期望的

wc -l *wc是数文件行的工具,绝对的简单傻,但是好用,man它一下吧)

  1000 pushListaa

  1000 pushListab

  1000 pushListac

  1000 pushListad

 。。。。。。

   282 pushListar

 17282 token.list

 34564 total

 

So far so good,看上去就剩下最后一步了,给分割出来的各个文件加上后缀。然后就到今天的主角出场了,铺垫很累人的,有木有。

按照我的习惯,首先把循环的架子写好如下

for i in `ls push*`;do echo $i;done;(作为注释,俺觉得这行的信息量很大。注释兄,闲话少说,阿里人很忙的好吧。

首先,三个分号分隔出来的三部分,被shell认为是三个完整语句,你其实可以输入到for i in `ls push*`;然后回车,你会发现屏幕上给出的是一个继续输入的提示如下,

for i in `ls push*`;

然后你可以输入第二段do echo $i;然后回车,还是继续输入的提示

for i in `ls push*`;

> do echo $i;

最后你输入第三段done;回车后就得到输出了。这和写在一行的效果一样。

 

然后我们来看第一段for i in `ls push*`;特意放大一点,for循环命令,i循环变量,这里其实相当于赋值,或者说左值,不用带$符号,in表示后面要跟枚举值了。再往后是一对引号,但是这里的引号不是单引号,而是反引号,在键盘的数字1的左边那个(或是esc键下面那个)。反引号范围里是一个shell命令,它将先被执行,然后替换反引号所在的位置。

 

ls push*将会列出当前目录下,所有以push开头的文件,*是通配符啊,这也是一种shell的基础设置,表示匹配0个或是多个任意字符,如此就把输入文件token.list给滤掉了。有等同效果的实现,比如用part1讲到的grep,这样写ls|grep push也很ok

 

所以实际上for执行时的命令行已经是for i in pushListaa  pushListac  pushListae  pushListag  pushListai  pushListak  pushListam  pushListao  pushListaq pushListab  pushListad  pushListaf  pushListah  pushListaj  pushListal  pushListan  pushListap  pushListar;,反引号替换威武吧。

 

然后看第二段do echo $i;do是循环体开始的标示,echo,是打印命令,一贯的又傻又天真,非常符合阿里价值观,$i是对循环变量的使用,或者说是右值,这就需要带上$符号了。

 

最后一段done;do对应,表示了循环体的结束。

pushListaa

pushListab

pushListac

pushListad

。。。。。。

 

先写循环的架子我觉得是个好习惯,首先是因为写在一行的for循环其实蛮容易写错的,经常会少写了一个分号,少写了一个do,先把架子写好,把循环的变量打印出来,那之后对循环变量的操作就能确定是靠谱的了。

 

for i in `ls push*`; do echo $i; mv $i $i.custom.txt;done;ls -l;(还是用上箭头翻出来,在done语句的前面写一个mv命令,mv $i $i.custom.txt;两个出现$i将会被替换成循环变量。循环完成,done之后用ls命令把当前目录的文件打出来看看)

 

-rw-r--r-- 1 mengchang users  10587 Nov 15 11:08 pushListaa.custom.txt

-rw-r--r-- 1 mengchang users  10845 Nov 15 11:08 pushListab.custom.txt

-rw-r--r-- 1 mengchang users  10609 Nov 15 11:08 pushListac.custom.txt

。。。。。。

-rw-r--r-- 1 mengchang users   3035 Nov 15 11:08 pushListar.custom.txt

-rw-r--r-- 1 mengchang users 184664 Nov 14 09:43 token.list

 

分割文件,重命名的case就打完收工了。

 

Shell中的for还有一个我极为常用的范式,就是配合seq命令执行次数确定的循环操作。超有用的,给大家show一下。

很傻很天真的seq怎么用,let’s man。

man seq

SEQ(1)                           User Commands                          SEQ(1)

 

NAME

       seq - print a sequence of numbers

 

SYNOPSIS

       seq [OPTION]... LAST

       seq [OPTION]... FIRST LAST

       seq [OPTION]... FIRST INCREMENT LAST

 

seq就是打印一个数字序列的命令啊,天生配合for使用。那么当一个case是把某个操作重复n遍,you know how to do

for i in `seq 5 10`;do echo $i;date;echo "do something";sleep 2;done;seq产生510的数字序列,由于放置于反引号中,将先于循环for执行,生成5 6 7 8 9 10作为for循环的枚举循环取值,

date是打印时间的函数,很有用,很多参数,值得一man

sleep是睡神,大家膜拜一下,单位是秒,

所以上面这个循环就是要循环5次,在每次循环里面,打印循环变量,打印当前时间,睡两秒)

5

Thu Nov 15 13:55:01 CST 2012

do something

6

Thu Nov 15 13:55:03 CST 2012

do something

7

Thu Nov 15 13:55:05 CST 2012

do something

8

Thu Nov 15 13:55:07 CST 2012

do something

9

Thu Nov 15 13:55:09 CST 2012

do something

10

Thu Nov 15 13:55:11 CST 2012

do something

 

for配合反引号的用法只是我最常用的,反引号可以用$()等价替换,for i in `ls`等价于for i in $(ls)。这里又会扯出关于括号的一堆事,我给个文档看看吧

 

 

关于shell的for循环的http://www.linuxdiyf.com/viewarticle.php?id=206569

 

关于shell各种括号的http://xuke1668.blog.51cto.com/2129485/853107

 

今天本来还要写if条件判断的,写不动了,好多事。下回继续。

源码直接下载地址: https://pan.quark.cn/s/95437fdf229e Intel I-219V网卡驱动是一款专门为Intel的I-219V千兆以太网控制器而研发的驱动程序,其主要作用在于保障在Ubuntu 16.04操作系统环境下的正常运作以及优化系统性能。Intel I-219V作为一款广泛应用的内置网络接口控制器(NIC),常被集成在台式机及笔记本电脑的主板上,负责提供高速的网络连接服务。Intel公司所提供的e1000e驱动是与此硬件相配套的开源驱动解决方案,其中版本3.3.5.3是专门针对该硬件设备的定制版本。此驱动包含了不可或缺的源代码部分,赋予开发者和系统管理者按照特定需求进行编译和定制的权限,从而能够适应多样化的系统配置或针对特定情形进行问题解决。源代码的可用性同样表明用户有能力依据Linux内核的更新情况来升级驱动,确保与最新技术标准的兼容性。在Ubuntu 16.04系统中成功编译的驱动意味着它已经通过了严苛的测试流程,并能够与该版本的Linux内核实现良好兼容。Ubuntu 16.04,其代号为Xenial Xerus,是一个长期支持(LTS)的版本,因此对于那些追求系统稳定性和安全保障的用户群体而言具有特殊的意义。驱动程序的兼容性保障了I-219V网卡能够在该系统平台上实现无缝运行,提供稳定可靠的网络连接,这既包括局域网(LAN)的连接,也可能涵盖通过Wi-Fi桥接实现的无线网络连接。驱动程序的核心职责涵盖了网络接口的初始化与管理、数据包的接收与发送处理,以及错误检测与纠正功能的执行。在Linux操作系统架构中,驱动通常以模块的形式加载至内核之中,这种设计允许在非必要时期进行卸载操作,以此来有效节省系统资源。e1000e驱...
内容概要:本文围绕基于共识的捆绑算法(CBBA)在多智能体系统中的多任务分配问题展开研究,重点应用于远程太空船交会与维修的相对轨道操作(RPO)规划。通过Matlab代码实现了CBBA算法,系统地解决了多个航天器在复杂空间环境下协同执行多目标任务时的任务分配、路径规划与动态协商问题。研究详细展示了算法在任务分解、竞标机制、共识达成及冲突消解等方面的核心逻辑,验证了其在分布式决策、通信受限条件下的高效性与鲁棒性,并结合航天工程实际背景突出了算法的应用价值。该资源不仅提供完整的仿真代码,还包含详细的流程解析,有助于深入理解多智能体协同机制的设计原理。; 适合人群:具备控制理论、航天器动力学、多智能体系统或分布式优化背景的研究生、科研人员及航空航天领域工程技术人员,熟练掌握Matlab编程者尤佳。; 使用场景及目标:①应用于在轨服务、空间碎片清除、多航天器编队飞行、星座维护等多智能体协同任务的任务分配与规划;②为研究人员提供CBBA算法的实现范例,支撑其开展分布式任务规划算法的改进与扩展研究;③作为教学案例用于高级课程中讲解多智能体协同决策机制。; 阅读建议:建议结合Matlab代码逐模块分析算法实现过程,重点关注任务打包、竞标更新、共识收敛等关键环节,可尝试引入通信延迟、故障容错或障碍规避机制以进一步提升算法实用性。
内容概要:本文介绍了一种基于关键场景辨别算法的两阶段鲁棒微网优化调度方法,旨在有效应对风电等可再生能源出力不确定性带来的调度挑战。通过Matlab代码实现,构建了包含预调度与实时调整的两阶段鲁棒优化模型,第一阶段制定初始调度计划以应对不确定性,第二阶段根据实际运行数据进行修正,从而提升微网运行的经济性与可靠性。该方法结合场景生成与缩减技术,识别关键不确定性场景,降低计算复杂度,同时增强了调度方案的鲁棒性。文中还探讨了该方法与智能优化算法、机器学习及电力系统仿真工具的集成应用,展现了其在复杂综合能源系统中的广阔应用前景。; 适合人群:具备一定电力系统基础知识和Matlab编程能力,从事新能源、微网优化、不确定性建模与鲁棒调度等领域研究的科研人员、工程技术人员及研究生。; 使用场景及目标:①应用于高比例可再生能源接入的微电网优化调度,提高系统对源荷不确定性的适应能力与运行稳定性;②为科研人员提供可复现的两阶段鲁棒优化建模与求解范例,支撑高水平学术论文的复现、算法改进与创新研究。; 阅读建议:建议结合提供的Matlab代码与网盘资料,动手实践关键场景生成、不确定性建模、两阶段优化建模与求解全过程,重点关注鲁棒优化框架的设计逻辑与关键场景辨别的实现机制,同时参考文中提及的多种算法与工具,拓展研究思路与应用场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值