perl 语言是用于文本处理语言,它代表实用提取和报告语言,可在各种平台运行(windows unix等)
安装perl 软件
perl -v # 检查版本信息
从官网下载perl 软件后,直接将程序添加到环境变量即可。
注意事项(链接:https://www.perl.org/get.html):
Perl 在 Window 平台上有 ActiveStatePerl 和 Strawberry Perl 编译器。
ActiveState Perl和 Strawberry Perl最大的区别是 Strawberry Perl 里面有多包含一些 CPAN 里的模块, 所以Strawberry Perl 下载的安装文件有 80多M, 而ActiveState Perl 只有20M 左右。
我们这里使用了 Strawberry Perl 。
windows 安装 perl 后,可以直接实用 Perl + perl 脚本运行(以pl 为文件后缀)
比如:打印 hello world
# print 打印函数
print "Hello, world\n";
perl 脚本注释
#注释一 #
#注释二 =cut *** =cut
=cut #begin comment
This is all part of multiline comment.
You can use as many lines as you like
These comments will be ignored by the
compiler until the next =cut is encountered.
=cut
空格: 不做处理
单引号:单引号不插入任何变量或特殊字符
双引号: 双引号插入变量和特殊字符(例如换行符\n)
测试用例:
# 注释
print "hello world\n";
$str1 = "str1 hello world\n";
$str2 = 'str2 hello world\n';
print "$str1 $str2\n";
print '$str1 $str2\n';
running:
hello world
str1 hello world
str2 hello world\n
$str1 $str2\n
perl 中转义字符
\" \r \n 等 会影响print 的输出
perl 标识符
Perl标识符是用于标识变量,函数,类,模块或其他对象的名称。Perl变量名称以$,@或%开头,后跟零个或多个字母,下划线和数字(0至9)。
Perl不允许在标识符内使用标点符号,例如@,$和%。Perl是区分大小写的编程语言。
标量 数组 哈希
变量修饰符
1)my 作用:把变量的名字和值都限于某个范围内,也就是说,该变量只能本层模块或者函数
可以看到这个变量,高一层或者低一层的都看不到。
2)our 作用:把变量名字限于某个范围,其实就是明确声明一个”全局变量”,虽然是在某个
模块或者函数里面定义,外面的也可以访问,如果已经声明过了,再次用our,表示此处用的和之前声明的our变量
是同一个。
3)local 作用:把值局限于某个范围,该范围与my有所区别的是,包含本层及本层的下层,
但本层的上一层不可以访问。
测试用例:
# 变量 以$开头的
$test = "this is a value";
# 数组 以@开头的
@day = ("Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday");
# 哈希 以%开头的
%table = ("xiaoming",25,"xiaohong",28,"xiaoli",24);
print "$test\n";
print "@day[0] @day[1] @day[2] @day[3] @day[4] @day[5]\n";
print "xiaoming: @table{xiaoming} xiaohong: @table{xiaohong} xiaoli: @table{xiaoli}\n";
rinning:
this is a value
Monday Tuesday Wednesday Thursday Friday Saturday
xiaoming: 25 xiaohong: 28 xiaoli: 24
序号数组:Perl提供了用于连续数字和字母的快捷方式
数组大小:
@day = ("Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday");
$size = @day;
$max_ind = $#day;
print "$size \n";
print "$max_ind \n"
数组元素添加与删除,函数操作
函数 | 类型 | 描述 |
---|---|---|
push | push @ARRAY, LIST | 将列表的值压入数组的末尾。(尾增) |
pop | pop @ARRAY | 弹出并返回数组的最后一个值。(尾删) |
shift | shift @ARRAY | 将数组的第一个值移开并返回,将数组缩短1并向下移动所有内容。(头删) |
unshift | unshift @ARRAY, LIST | 将列表添加到数组的最前面,并返回新数组中的元素数。(头增) |
splice | splice @ARRAY, OFFSET [ , LENGTH [ , LIST ] ] | 更换数组中元素 偏移 长度 更换值 |
split | split [ PATTERN [ , EXPR [ , LIMIT ] ] ] | 字符串拆分数组 |
join | join EXPR, LIST | 数组变成字符串 |
sort | sort [ SUBROUTINE ] LIST | 数组排序 |
哈希定义(键和值):
%data = ('John Paul' => 45, 'Lisa' => 30, 'Kumar' => 40);
获取键(keys)和值(values)的函数
测试用例:
@test = (1..10);
print "@test\n";
%table = ("xiaoming",25,"xiaohong",28,"xiaoli",24);
#相同含义
#%table = ('xiaoming',25,'xiaohong',28,'xiaoli',24);
#%table = ('xiaoming'=>25,'xiaohong'=>28,'xiaoli'=>24);
print "@table{xiaoming} @table{xiaohong} @table{xiaoli}\n";
@test_key = keys %table;
@test_value = values %table;
print "@test_key @test_value";
running:
1 2 3 4 5 6 7 8 9 10
25 28 24
xiaoli xiaohong xiaoming 24 28 25
哈希需要计算大小,需要获取出其keys 或者values 变成数组,计算其大小
哈希的添加删除
# 哈希添加删除
%data = ('John Paul' => 45, 'Lisa' => 30, 'Kumar' => 40);
@keys = keys %data;
$size = @keys;
print "1 - Hash size: is $size\n";
# adding an element to the hash;
$data{'Ali'} = 55;
@keys = keys %data;
$size = @keys;
print "2 - Hash size: is $size\n";
# delete the same element from the hash;
delete $data{'Ali'};
@keys = keys %data;
$size = @keys;
print "3 - Hash size: is $size\n";
++if语句++
if(boolean_expression) {
# statement(s) will execute if the given condition is true
}
#例如
if(boolean_expression 1) {
# Executes when the boolean expression 1 is true
} elsif( boolean_expression 2) {
# Executes when the boolean expression 2 is true
} elsif( boolean_expression 3) {
# Executes when the boolean expression 3 is true
} else {
# Executes when the none of the above condition is true
}
++unless语句++
unless(boolean_expression 1) {
# Executes when the boolean expression 1 is false
} elsif( boolean_expression 2) {
# Executes when the boolean expression 2 is true
} elsif( boolean_expression 3) {
# Executes when the boolean expression 3 is true
} else {
# Executes when the none of the above condition is met
}
++switch语句++
use Switch;
switch(argument) {
case 1 { print "number 1" }
case "a" { print "string a" }
case [1..10,42] { print "number in list" }
case (\@array) { print "number in list" }
case /\w+/ { print "pattern" }
case qr/\w+/ { print "pattern" }
case (\%hash) { print "entry in hash" }
case (\&sub) { print "arg to subroutine" }
else { print "previous case not true" }
}
三目运算符 ? : 与c语言一致
++while++ 循环
while(condition) {
statement(s);
}
do {
statement(s);
}while( condition );
**++for循环语句++
**
for ( init; condition; increment ) {
statement(s);
}
无限循环
for( ; ; ) {
printf "这里将永远执行.\n";
}
while( true ) {
printf("这里将永远执行.\n");
}
循环类型 | 描述 |
---|---|
while循环 | 在给定条件为真时重复一个语句或一组语句。它在执行循环体之前测试条件 |
until循环 | 重复一个语句或一组语句,直到给定条件变为真为止。它在执行循环体之前测试条件。 |
for循环 | 多次执行一系列语句,并简化管理循环变量的代码。 |
foreach 循环 | foreach循环遍历常规列表值,并将变量var 依次设置为列表的每个元素。 |
do… while循环 | 它更像while语句,除了它在循环主体的末尾测试条件(do…while循环至少会执行一次)。 |
嵌套循环 | 您可以在任何其他while,for或do…while循环内使用一个或多个循环 |
测试用例:
$tmp = 30;
@pl_value = (15..35);
#for($index=15;$index<35;$index=$index+1)
for( $index = 10; $index < 20; $index++ )
{
if(@pl_value[$index] >= 30)
{
#print "the value is @pl_value[$index]\n";
use Switch;
switch(@pl_value[$index])
{
case 30 {print "the value is @pl_value[$index]\n"}
case 31 {print "the value is @pl_value[$index]\n"}
case 32 {print "the value is @pl_value[$index]\n"}
case 33 {print "the value is @pl_value[$index]\n"}
case 34 {print "the value is @pl_value[$index]\n"}
case 35 {print "the value is @pl_value[$index]\n"}
else {print "the value is null"}
}
}
}
runningL:
the value is 30
the value is 31
the value is 32
the value is 33
the value is 34
#foreach 测试
@list = (2, 20, 30, 40, 50);
# foreach loop execution
foreach $a (@list) {
print "value of a: $a\n";
}
rinning:
value of a: 2
value of a: 20
value of a: 30
value of a: 40
value of a: 50
++循环使用关键字++
next continue last goto
perl 支持的运算符如下
操作符 | 描述 | 例子 |
---|---|---|
+ | 加两个操作数。 | $a + $b将得到30 |
- | 从第一个减去第二个操作数。 | a − a- a−b将得到-10 |
* | 将两个操作数相乘。 | $a * $b将给出200 |
/ | 将分子除以除分母。 | $b / $a将给出2 |
% | 模运算符和整数除法后的余数。 | $b % $a将给出0 |
** | 对运算符执行指数(幂)计算 | $a ** $b将得到10的20次方 |
操作符 | 描述 | 例子 |
---|---|---|
== | 检查两个操作数的值是否相等。如果是,则条件变为真。 | ($a == $b)为false。 |
!= | 检查两个操作数的值是否相等。如果值不相等,则条件为真。 | ($a != $b)为true。 |
<=> | 检查两个操作数的值是否相等,并根据左参数在数值上小于,等于或大于右参数而返回-1、0或1。 | ($a <=> $b)为 -1。 |
> | 检查左操作数的值是否大于右操作数的值。如果是,则条件变为真。 | ($a > $b) 为false。 |
< | 检查左操作数的值是否小于右操作数的值。如果是,则条件变为真。 | ($a < $b)为true。 |
>= | 检查左操作数的值是否大于或等于右操作数的值。如果是,则条件变为真。 | ($a > = $b)为false。 |
<= | 检查左操作数的值是否小于或等于右操作数的值。如果是,则条件变为真。 | ($a <= $b)为true。 |
操作符 | 描述 | 例子 |
---|---|---|
lt | 如果left参数在字符串上小于right参数,则返回true。 | ($a lt $b) 为 true. |
gt | 如果left参数在字符串上大于right参数,则返回true。 | ($a gt $b) 为 false. |
le | 如果left参数在字符串上小于或等于right参数,则返回true。 | ($a le $b) 为 true. |
ge | 如果left参数在字符串上大于或等于right参数,则返回true。 | ($a ge $b) 为 false. |
eq | 如果left参数在字符串上等于right参数,则返回true。 | ($a eq $b) 为 false. |
ne | 如果left参数沿字符串方向不等于right参数,则返回true。 | ($a ne $b) 为 true. |
cmp | 返回-1、0或1,具体取决于左参数是按字符串方式小于,等于还是大于右参数。 | ($a cmp $b) 为 -1. |
操作符 | 描述 | 例子 |
---|---|---|
= | 简单的赋值运算符。将值从右侧操作数分配给左侧操作数 | $c = $a+ b 将 b将 b将a + b 的 值 赋 给 b的值赋给 b的值赋给c |
+= | 加和赋值运算符。它将右操作数添加到左操作数,并将结果分配给左操作数。 | $c + = a 等 于 a等于 a等于c = $c + $a |
-= | 减和赋值运算符。它从左侧操作数中减去右侧操作数,并将结果分配给左侧操作数。 | $c-= a 等 效 于 a等效于 a等效于c = c − c- c−a |
*= | 乘以和赋值运算符。它将右操作数与左操作数相乘,并将结果分配给左操作数。 | $c * = a 等 效 于 a等效于 a等效于c = $c * $a |
/= | 除和赋值运算符。它将左操作数除以右操作数,并将结果分配给左操作数。 | $c / = a 等 于 a等于 a等于c = $c / $a |
%= | 模和赋值运算符。它使用两个操作数取模,然后将结果分配给左操作数。 | $c%= a 等 于 a等于 a等于c = c % c% c%a |
**= | 指数和赋值运算符,对运算符执行指数(幂)计算并将值赋给左操作数 | c = $ a等效于$c = $c $a |
&,|和^
操作符 | 描述 | 例子 |
---|---|---|
and | 称为逻辑AND运算符。如果两个操作数都为真,则条件为真。 | ($a and $b)为false。 |
&& | 称为逻辑与运算符。如果两个操作数都不为零,则条件变为true。 | ($a && $b)为false。 |
or | 称为逻辑或运算符。如果两个操作数中的任何一个都不为零,则条件为真。 | ($a or $b)为true。 |
not | 称为逻辑非运算符。用于反转其操作数的逻辑状态。如果条件为真,则逻辑非运算符将为假。 | !($a && $b)为false。 |
操作符 | 描述 | 例子 |
---|---|---|
q {} | 用单引号将字符串引起来 | q {abcd} 得 ‘abcd’ |
qq {} | 用双引号将字符串引起来 | qq {abcd} 得 “abcd” |
qx {} | 用反引号引起来的字符串 | qx {abcd} 得 abcd |
操作符 | 描述 | 例子 |
---|---|---|
. | 二进制运算符点(.)连接两个字符串 | 如果 a = “ a b c ” , a=“abc”, a=“abc”,b =“def”,则 a . a. a.b将 得到 “abcdef” |
x | 重复运算符x返回由左操作数组成的字符串,该字符串重复了右操作数指定的次数。 | (‘-’ x 3)将得到 —。 |
… | 范围运算符…返回从左值到右值计数(逐个递增)的值列表 | (2…5)将得到(2,3,4,5) |
++ | 自动增量运算符将整数值增加一 | $a++将给出11 |
– | 自动减量运算符将整数值减一 | $a–将给出9 |
-> | 箭头运算符主要用于从对象或类名中解引用方法或变量 | o b j − > obj-> obj−>a是从对象 o b j 访 问 变 量 obj访问变量 obj访问变量a的示例。 |
相关函数
函数一:
localtime() #系统时间
#time相关函数
$time = localtime();
print "$time\n";
#output
Tue May 10 11:43:30 2022
函数二:
gmtime() #utc时间 不带tz
$time1 = gmtime();
print "$time1 \n";
#output
Tue May 10 03:49:08 2022
函数三:
time() #1970年到现在的秒数
$time2 = time();
print "$time2 \n";
#output
1652154548
函数四:
sleep
$time = localtime();
print "$time\n";
$time1 = gmtime();
print "$time1 \n";
$time2 = time(); #1970年到现在的秒数
print "$time2 \n";
sleep 5;
$time4 = localtime();
print "$time4 \n";
$time3 = localtime($time2); #1970 s转换成时间
print "$time3 \n";
函数五:
strftime() #格式化输出时间
use POSIX qw(strftime);
print strftime("%Y-%m-%d %H:%M:%S\n", localtime(time));
#Output
2022-05-10 13:18:40
函数定义
sub subroutine_name {
body of the subroutine
}
传参:@_ 接收
return 返回值
test 一:
函数定义与传参,返回值
#function
sub test_add
{
print "this is a function @_[0] @_[1] @_[2] \n";
return @_[0]+@_[1]+@_[2]
}
$ret = test_add(10,20,30);
print "this value is $ret \n";
test 二:
数组传参
#function 数组传参
sub test_add
{
$test_size = @_;
$add_value = 0;
print "this is a function $test_size \n";
while($test_size >= 0)
{
$add_value = $add_value + @_[$test_size];
$test_size --;
print "this value is $add_value \n";
}
return $add_value;
#return @_[0]+@_[1]+@_[2]
}
@test = (10..15);
$ret = test_add(@test);
print "this value is $ret \n";
test 三:
哈希传参
#function 哈希传参
sub test_add
{
$test_size = @_;
$add_value = 0;
print "this is a function $test_size \n";
while($test_size >= 0)
{
print "[test_add]this value is @_[$test_size-1] \n";
$test_size --;
}
%table = @_;
@test_key = keys %table;
@test_value = values %table;
print "@test_key @test_value \n";
return 0;
}
@test = ("xiaoming",25,"xiaohong",28,"xiaoli",24);
$ret = test_add(@test);
print "this value is $ret \n";
open 操作
print 写入文件
# Open file
open(DATA1, "+>file1.txt");
#write file1
print DATA1 "/*-------------------------------------------------------------\n";
print DATA1 "** file name: quectel_test.c\n";
print DATA1 "** function: feature control\n";
print DATA1 "** create date: localtime()\n";
print DATA1 "*-------------------------------------------------------------*/\n";
print DATA1 "#define QUECTEL_TEST1\n";
print DATA1 "#define QUECTEL_TEST2\n";
print DATA1 "#define QUECTEL_TEST3\n";
# Open new file to write
open(DATA2, ">file2.txt");
# Copy data from one file to another.
while(<DATA1>) {
print DATA2 $_;
}
close( DATA1 );
close( DATA2 );
实体 | 定义 |
---|---|
<或r | 只读访问 |
>或w | 创建,写入和截断 |
>>或> | 编写,附加和创建 |
+<或r+ | 读写 |
+>或w+ | 读取,写入,创建和截断 |
+>>或a+ | 读取,写入,附加和创建 |
getc 函数
getc 函数从指定的FILEHANDLE中返回单个字符,如果未指定则返回STDIN-
read 函数
read 函数从缓冲的文件句柄中读取信息块:此函数用于从文件中读取二进制数据。
warn 函数
warn 函数仅会发出警告,一条消息会打印到STDERR,但不会采取进一步措施。因此,如果您只想为用户打印警告并继续进行其余操作,它会更有用-
die 函数
die 函数的作用与 warn 相似,只是它还会调用 exit。在普通脚本中,此函数具有立即终止执行的作用。如果程序中有错误,则应使用此功能以防继续进行-
excel 环境需要安装WriteExcel 插件(暂时先不搞了 环境一直有问题)
注意事项:安装cpanm 安装模块
1.安装perl
2.dmake:
http://mirrors.163.com/cpan/authors/id/S/SH/SHAY/dmake-4.12.2.2.zip
3.cpanm(App::cpanminus):
http://mirrors.163.com/cpan/authors/id/M/MI/MIYAGAWA/App-cpanminus-1.7040.tar.gz
4. 安装perl并添加环境变量(exe文件里面有提示添加,可以在那里添加即可,假设Perl安装路径是D:\Perl64)。
3. 将dmake-4.12.2.2.zip解压,把 startup 文件夹和 dmake.exe 文件放入D:\Perl64\bin
4. 解压App-cpanminus-1.7040.tar.gz 到任意目录,cmd窗口进入,输入如下命令:
perl Makefile.PL
dmake test
dmake install
5.使用cpanm 安装缺少的模块
操作excel(使用OLE模块) 实例
use Win32::OLE qw(in with);
use Win32::OLE::Const 'Microsoft Excel';
$AT_LIST_XLS = "test.xlsx";
$sheetname = "at";
my $Excel = Win32::OLE->GetActiveObject('Excel.Application')
|| Win32::OLE->new('Excel.Application', 'Quit'); # get already active Excel
# application or open new
#新建
#my $Book = $Excel->Workbooks->add;
#my $Sheet = $Book->Worksheets(1);
#打开已经有的
my $Book = $Excel->Workbooks->Open($AT_LIST_XLS); # open Excel file
my $Sheet = $Book->Worksheets($sheetname);
$row = 1;
$col = 1;
while(1)
{
$ret = $Sheet->Cells($row, $col)->{'Value'}; #取值 根据行和列
if (length($ret) == 0) #读到第一列如果为空,不再继续读,退出excel
{
last;
}else
{
$Sheet->Cells($row, $col+1)->{'Value'} = send_at($ret); #写值 根据行和列
}
$row++;
#send_at($ret);
}
$Book->SaveAs($AT_LIST_XLS);
$Book->Close;
json 安装json模块
xml 安装xml 模块
注意事项: SerialPort这个模块的使用 需要安装perl Strawberry版本 否则会报错
操作窗口设备 发送at指令
#强制全局变量用my修饰
use strict;
#使用串口模块
use Win32::SerialPort;
#定义串口,并打开它
my $testPORTNAME = "COM13";
my $ob = Win32::SerialPort->new($testPORTNAME) || die "open com failed";
print "open com success\n";
#配置串口设置
eval {
$ob -> baudrate( 115200 ); #如果使用超过115200的波特率,执行脚本前先用串口通信工具用对应波特率打开串口,发个AT。
$ob -> parity( 'none' );
$ob -> databits( 8 );
$ob -> stopbits( 1 );
#$ob -> handshake( 'rts' ); #硬件流控
$ob -> handshake( 'none' ); #无流控
#$ob->buffers(4096, 4096);
};
if ($@) { die ' set $testPORTNAME properties failed ' ;}
$ob -> write_settings || die " CANNOT WRITE $testPORTNAME DRIVER ";
#发送at命令
$ob->write ("ATI\r\n"); #写到串口
sleep(1);
#读取命令返回值
my($count, $string) = $ob->read(100); #从串口读100字节数据,读到的数据长度$count, 数据赋值给$string
if(defined($string)) #读到了数据
{
print $string;
}
$ob->close; #关闭串口
undef $ob ;
exit(0);
测试结果如下:
open com success
ATI
Quectel
EC20F
Revision: EC20CEFARGR06A03M4G_OCPU
OK