perl常问题集合之一

by admin on 2020年2月15日

图片 1

Linux的 rename
命令有两个版本,一个是C语言版本的,一个是Perl语言版本的,早期的Linux发行版基本上使用的是C语言版本的,现在已经很难见到C语言版本的了,因为Perl版本的支持正则处理,所以功能更加强大,已经不再需要C语言版本的了。

Perl是什么?

最近,perl6 的 GitHub 仓库上进行了一场讨论,关于 perl6
应不应该重新命名。

如何区分系统里的rename命令是哪个版本的?

  Perl是一个高阶程式语言,由 Larry
Wall和其他许多人所写,融合了许多语言的特性。它主要是由无所不在的
C语言,其次由 sed、awk,UNIX shell
和至少十数种其他的工具和语言所演化而来。Perl对
process、档案,和文字有很强的处理、变换能力,因此举凡有关快速原型设计、系统工具、软体工具、系统管理、资料库连结、图像程式设计、网路连结,和
WWW程式设计等之类的任务,都特别 适合用 Perl来做。这些特长不但使
Perl成为系统维护管理者和
CGI作者的宠儿,就连数学家、遗传学家、新闻从业者,甚至企业管理者也都用
Perl,所以或许您也该用。

perl6 的大多数用户认为,perl5 的印象留给人的太深了,人们无法区分 perl5
和 perl 6,并且这些人都认为 perl6 是 perl5
的下一个版本,只是版本号存在差异而已。

输入 man rename 看到第一行是

  谁对 perl提供支援?由谁负责发展?它为什麽是免费的?

这完全会混淆两者,其实“两种编程语言”有很大不同,是不兼容源代码的,perl5
是用 C 写的核心,虽然已经很成熟,但核心代码太庞大,perl6 相对 perl5
做出了革命性的变革,新的内核更小、速度更快、外部扩展 API
更加清晰,简直就是轻松上路的骆驼。而这些人就认为应该给 perl6 更改名称。

RENAME(1) Linux Programmer’s Manual RENAME(1)

  Perl自由开放的发行方式要归功於发烧前的 Internet的传统文化及其作者
Larry Wall。Perl是由使用者提供支援。现在
Perl的核心、标准程式库、选择性安装的模组,以及您现在正在阅读的使用说明都出自於义务者之手。详情请见
perl原始码发行版中所附的 README档案底部的私人注记。

用户 lizmat 建议将 perl6 改为“Camelia
Programming Language”或简称“Camlia”(还有人认为改成 Raku
等等),并且列举一下几点:

那么 这个就是C语言版本的。

  值得一提的是,核心发展小组(称为 Perl
Porters)的成员是一群高度热情奉献的人仕,全心投入发展出比您所能想像、用钱能买得到还要更好的免费软体。您可经由
news://genetics.upenn.edu/perl.porters-gw/ 和 http:
//www.frii.com/~gnat/perl/porters/summary.html取得关於新近发展计画
的情报。

  • 将名字改为 Camlia 将对 Google 和 DuckDuckGo
    等搜索引擎来说,易于搜索,不会混淆
  • logo / mascot 不需要改变
  • Camlia 这个名字,仍然带有 Perlish  的意义
  • Camlia 是 roast 中一个规范的实现
  • Camella 标识仍然会属于其作者 Larry Wall 的版权

而如果出现的是:
RENAME(1)              Perl Programmers Reference Guide             
RENAME(1)

  尽管 GNU计画将 Perl囊括在它的发行中,但是没有叫「GNU
Perl」这样的东西。
Perl既非自由软体基金会所创,亦非由其负责维护。Perl的发行条款同时也较
GNU软体更来得开放。

图片 2

这个就是Perl版本的了!

  如果您愿意,您可以购买商业性的
Perl支援。但对大多数使用者来说,非正式性的支援通常已相当足够。详情请见「到哪里可买到商业性的
Perl支援」一问的回 答。

lizmat 的观点得到一些人的认同,他们表示在今天,很多人只是错误地将 perl5
认为是旧版本,perl6 是新版本。perl6 其实是一种新的语言,相比
perl5,它具有更小的社区和生态系统,就像每一种新语言一样,需要找到自己的方法来更广泛地使用。当然有一点必须承认,到目前为止,它还是站在老语言的肩膀上。

两个版本的语法差异:

  我该用哪一个版本的 Perl?

有的人表示则不在意它是否重命名,这部分人表示重命名会导致很多各种各样的问题,而相比名字本身,更关心的是语言本身。

C语言的,按照man上面的注解,
rename的语法格式是:

  您绝对该用第五版。第四版不但老旧、功能较局限,而且已经不再维护了。它最後
一次的修正 (4.036)是在 1992年。Perl最新的量产发行版本是5.004。等到您
读这篇文章时,我们可能已经又发行了几个正式的除错版本,同时大概又会有些替
下一版 路的实验版出来。本文由此开始凡提及 Perl语言,皆以目前的量产发行
为准,除非另外特别注明。

有的人认为改名在某种意义上意味与历史决裂,与之前的版本划清界限。很多人因为将
perl5 和 perl6 混淆了,然后渐渐离开了它,如果把 perl6
命名为 Camlia,那些离开的的人也不会回来。perl 6
作为一个名字已经出现了十几年,如果有人看到 perl6
的消息,可能还会吸引他们的注意力,想到他们之前用过这个语言,可能想着它是不是做了什么新鲜的改变,说不定会回来瞅一眼。如果更改
perl6 的名字,对 perl5 也不是一件什么好事,Perl5 也需要证明自己还活着。

rename from to file

  perl4和 perl5各代表什麽?
  perl4 和 perl5 是对
Perl程式语言的两个不同版本的非正式称呼,因为说「perl5」要比说「第
5(.004)版的
Perl」要来得简单。但是有些人误将其会意为:perl5是一个单独的语言;这是不正确的。perl5只不过是对第五个主要发行版本(1994年
10 月)常用的称呼罢了。就像 perl4是指第四个主要发行(1991年 3 月),还有
perl1(1988年 1月)、perl2(1988 年 6 月),以及 perl3(1989年 10
月)。

Perl 是一个强大的品牌,我们不能忽视它在不使用 Perl 的人中已获得的声誉。

这个命令有三个参数,分别是 from : 修改什么名字, to:改成什么名字,
file 需要修改的文件是哪些。

  5.0的发行基本上是从零开始,所有程式码完全重新写过的版本。它已经被模组化、物件导向化、微调、精简化,及效率化,以致程式码几乎已变得和原来的不相同了。尽管如此,使用介面大致上仍然相同,而且和先前的版本之间保持了很高的
一致性。

关于这个观点讨论,每个人都是各有各的看法,各位看官怎么看?

用法示例:
比如,有一批文件,都是以 log开头的, log001.txt,  log002.txt …….
一直到 log100.txt
现在想要把这批文件的log全部替换为 history 
rename  log  history  log*

  为了避免「perl5是什麽语言?」这类的混淆,有些人索性完全避免「perl5」,
而单用「perl」来指称最近的 perl版本。其实用不着这麽累就是了。

(文/开源中国)    

这句命令的意思很明白了,把 以 log开头的所有文件中的 log字符替换为
history
这样替换后的文件是: history001.txt,  history002.txt ….. 一直到
history100.txt

  Perl的发展已稳定了吗?
  融合了除错和新功能的量产发行在推出前皆经过广泛的测试。自
5.000发行以来, 我们平均一年才出版一次量产发行。

rename C语言版本的另一个man示例是把后缀名批量修改,
比如我们要将所有 jpeg的后缀名图片文件修改为 jpg文件。

  Larry 和
Perl发展小组有时候会修改语言的核心部分,但总是尽一切力量让新版
和旧版保持一致。因此,尽管不是所有的 perl4 scripts都能在 perl5
之下跑得天衣无缝,因升级而导致按照先前版本的
perl所写的程式无法使用的情形几乎不曾发生(除非该程式倚赖已经被去除的
bugs,或使用了极少数新加入的指令来 命名)。

rename .jpeg .jpg *.jpeg

  Perl难学吗?

这样,所有以 .jpeg扩展的后缀名全部被修改为 .jpg

  Perl不但容易上手,也容易继续学下去。它看起来和大多数您可能已接触过的语言一样。所以如果您只写过
C 程式、或 awk script、shell script,或甚至只是 Excel的
macro(巨集),您已经在半路了。

现在总结一下rename C语言版本所能实现的功能:
批量修改文件名,结果是每个文件会被用相同的一个字符串替换掉!也就是说,无法实现诸如循环
然后按编号重命名!

  大多数的任务只需要 Perl语言的一小部分即可完成。发展
Perl程式的座右铭即 是「不只一种方法可以达到」(TMTOWTDI; There’s More
Than One Way To Do It,
有时读作「堤姆投迪」)。因此,Perl的学习曲线是既平(易学)且长的
(如果您要的话,有一大堆够您学的)。

2, Perl
版本的批量重命名,带有Perl的好处是,你可以使用正则表达式来完成很奇特的功能。

  最後,Perl(通常)算是解译式的语言。也就是说您写了程式後不需经由一道中
间的编码过程即可测试;这让您可以很快、很容易地测试及除错。这个方便试验的
特性又让学习曲线变得更加平坦。

perl 版本的参数格式:

  有助於修习 Perl
的一些事:UNIX经验、对几乎是任何一种程式语言的经验、了解 regular
expressions(正规表示法),以及看得懂旁人写的程式的能力。如果您有什麽想用
Perl来做的事,那麽可能已经有前人做过了,而且实例通常可免费取得。还有别忘了新的
Perl模组。模组在这份 FAQ
的第叁部分有详细的讨论,还有【别忘了您的好朋友】
CPAN,这会在第二部分谈到。

rename  perlexpr files

  Perl和其他的程式语言比起来如何?例如 Java, Python, REXX, Scheme,或
Tcl?

注意,perl版本的rename只有两个参数,第一个参数为perl正则表达式,第二个参数为所要处理的文件

  Perl在某些地方比较好,某些地方较差。精确地说到底哪些方面好或坏通常视个
人偏好而定,所以在新闻讨论群中问这种问题很可能会掀起一场毫无建设性的圣战。

man rename的帮助示例:

  要比较各语言的异同最好的方法是试着用不同的语言写功能相同的程式。各程式语言都各有属於它们各自的新闻讨论群,您可从中学习(但希望您不是去和人辨论吵
架的)。

1) 有一批文件,以 .bak结尾,现在想把这些 .bak 统统去掉。

  我可以用 Perl来做【某种差事】吗?

rename     ‘s/.bak$//’        *.bak

  Perl有足够的弹性和扩充性,从只需要写短短一行的档案处理工作到复杂的系统,几乎没有什麽做不到的。对有些人来说,Perl的是拿来做写
shell程式的理想替代品。其他人则用高阶的 Perl来替代处理许多原先需要用 C或
C++ 一类的低阶语言来达到的程式。哪些差事决定要用
Perl来处理,这一切都得看您(或许还有您的经理…)。

这个命令很简单,因为我还没有系统学习过perl,我不知道perl里替换字符串是不是这么干的,但sed是这么干的,所以如果你有sed或者tr基础,很容易明白,这个替换和sed里的正则语法是一模一样的。

  如果您有一个提供 API的程式库的话,您可用 C或 C++来写一个 Perl
延伸,然後便可透过它将程式库中的任何一部分动态载入您的
Perl主程式中。您也可以 反过来,用 C或
C++来写主程式,然後以即时动态载入的方式插入一些Perl程式码,产生一个威力强大的应用程式。

2) 把所有文件名内含有大小字母的,修改为小写字母。

  话虽如此,对解决某些特定的问题,使用小型、专精,专为特殊用途设计的语言总
是比较方便的。
Perl的设计是尽力地满足各种不同人的需要,因而不特别偏颇任何人。至於特殊功能语言的例子,随便举两个,譬如
prolog 和 matlab 便是。

rename      ‘y/A-Z/a-z/’        *


  哪些场合下不适合用 Perl?

  当您的主管禁止的时候 — 不过请务必考虑把他们换掉 。

依然和sed的替换语法一样,不用多解释,如果看不懂的话,可以系统学习一下sed先。

  说真的,如果您已经有用另一个语言写成的应用程式(而且写得很好)的时候,或
者是已经有替某些特定的工作设计的语言(例如:prolog, make),这个时候就不
需要用 Perl。

还有几个比较实用的例子:

  由於种种因素,Perl大概不太适合拿来做即时内嵌式系统、属於低层级的作业系统发展工作,例如周边设备的
drivers或环境转换码、复杂的多线共用记忆体应用程式,或非常大的应用程式。您会发现
Perl 本身便不是以 Perl写成的。

1) 批量去掉文件名里的空格 
Linux文件名本来是不支持空格的,不知道什么时候允许了,当然,在命令行调用文件的时候,空格是很有问
题滴,比如你 原来可以直接  mv  oldfile  newfile  但有空格就不行了 ,
得加双引号: mv “oldfile”  “newfile” 或者用反斜杠转移  []
,这样还好,但如果你直接把含有空格的图片名引入
Latex文档,Latex生成pdf的时候会直接打印出文件名,之前这个问题苦恼了我很久,我生成的pdf怎么老是出现文件名呢?后来才发现原来是文件
名内含有空格的问题!windows系统下生成的文件名是天生含有空格的,虽然很讨厌,但有些惠普扫描仪生成的图片默认就加入了空格,没有办法,只好去掉
他,在系统研究rename命令前,我是用 mv 去除空格的。

  刚出炉的
Perl纯码编译器或许可帮忙去除一些上述的限制,但您要了解:Perl在本质上仍是一活性变数语言
(dynamically typed language),而非固性变数 (statically
typed)。只要您不将核电厂或脑科手术监视器所用的程式放心地用
Perl来写,您自然就不会闯祸遭殃。这样 Larry晚上也可以睡得安稳些
–股市分析程式不在此限 。

网上流程的两个去空格的版本:

  「perl」和「Perl」有什麽不同?

1) tr 版:

  二者差一个位元。喔,您不是说在 ASCII上的差别啊? Larry
现在用「Perl」来代表语言本身,而以「perl」来表示该语言的体现,即目前的解译器。因此,作者有句幽默小语说:「只有
perl可以解译
Perl」。要不要遵照这个用法是您的自由。举一反叁的话,我们可依样画葫芦地说「awk
和 perl」还有「Python 和 Perl」,但却不可将「awk 和 Perl」或是「Python
和 perl」摆在一起。

find . -type f -name “* *” -print |
while read name; do
na=$(echo $name | tr ‘ ‘ ‘_’)
if [[ $name != $na ]]; then
mv “$name” $na
fi
done

  Perl程式应算是 program还是 script?

这个版本以前我一直用的,不知道哪个网上搜刮来的,当时还没有系统的学习过
tr/sed/awk命令。
注解一下,很好理解, find . type f -name “* *” -print
这一句是查找当前目录下所有类型为普通文件的
并且名字之中含有空格的文件,并打印出来,其实 find默认就是打印的 这个
-print 多余了,然后 通过管道传输给 while 循环读取,文件名放到 name
变量里,用 tr 命令 替换空格为 下划线。
下面判断如果执行后的名称不相同,使用 mv
命令重命名。但这个if判断可有可无,因为find已经查询了所有文件名中含有空格的,那么经过
tr 命令后, $na变量肯定不等于 $name 变量的。

  都无所谓。按标准术语来讲,program指已经由编译程序编译好、转为机器码,可多次执
行的程式;而
script则是每次执行时都必须透过一个解译程式来解译。然而,Perl程式严格说来,既非编译
(compiled) ,亦非解译式 (interpreted);因
Perl程式可转译成位元码形式存在(可说是某种 Perl虚拟机器 [virtual
machine]),或转译为完全不同的语言,如 C或组合语言。所以光看原始码很难
说它到底是替纯解译器、或是
parse-tree解译器、位元码解译器,还是纯码编译器而写;因此这题很难给它一个确切的答案。

所以这段代码可以简化:

  JAPH是什麽?   
  这是过去一些在讨论群中自称 “just another perl hacker”
的人的签名档,约有一百个比较早期的,可在
取得。

find . -type f -name “* *” |
while read name; do
na=$(echo $name | tr ‘ ‘ ‘_’)
mv “$name” “$na” 
done

  到哪儿可拿到 Larry Wall的智慧讽语 (witticisms)?

tr 可以看着是 sed 的一个精简版本,tr 用下划线来替换空格。

  一百多条 Larry的讽语,源自他【在讨论群】的
posts或原始码,可在 取得。

还有一个 是 sed 版本实现:

  我要如何取信、说服我的系统管理者/上司/属下使用第 5/5.004版的
Perl,而不去用其他的语言?
如果您的管理阶层或属下对没有支援的软体,或是未正式包含在所购买的作业系统中的软体存有戒心的话,您可以试着从有助他们自身利益这方面下手。因为如果程式设计师能由善加利用
Perl的结构、功能性、简单性,和威力而获得更大的生产力的话,那麽典型的管理者/上司/员工或许便可因而加以说服。此外,使用
Perl,总的来讲,和其他语言相较,或许也有助於减少交件的时间。强调这个论
点或许对说服他们会有帮助。

for f in *;do mv “$f” `echo “$f” | sed ‘s/[ ]+/_/g’ `; done

  如果您的专题碰到瓶颈,特别是有关转译或测试方面的问题,那麽
Perl可以说绝
对会是一个既可行且快的解决之道。您在当说客的时候,千万别忘了要提:Perl已
被世界上许多大型的软硬体公司广泛、大量地使用,极为可靠、有效。事实上,现
Perl已成为许多 Unix业者所售的作业系统的标准配备了。而且如果您无法在
详尽的使用说明,包括这份 FAQ之中为您的问题找到解答的话,送封 post
到新闻讨论群即可。

这里的 sed表达式还可以这样写:

  如果您面对反对 perl升级的声音,那麽告诉他们
Perl发展小组已经完全不再维护或支援第四版的
perl了。perl5的另一个大卖点是它有大量的模组和延伸,可大大减少计画的发展时间。还有,告诉他们第四和第五版
Perl之间的差异就如 awk 和
C++的差别一样(嗯,或许没有差得那麽明显,但您知道我的意思就好)。如果您想得到支援而且想确保您现在所发展的软体在未来能继续工作的话,那麽您得跑有支援的版本。这大概也就是说要跑
5.004 版的,尽管 5.003
版仍算是不错(它只落後一年、一版)。不过因为有些严重的 bugs曾在 5.000 和
5.002版之间被消除,所以您至少应升级到比这几个版本高才是。

sed ‘s/[[:space:]]+/_/g’

不过记住,sed里的出现一次或多次的加号是需要添加反斜杠的。即:+

这样就可以了。

好了,这两种办法都太他妈罗嗦了,看看rename实现吧:

rename      ‘s/[ ]+/_/g’        *

OK就这么简单。
方括号内的空格可以用 [:space:]代替,
即可以写成 ‘s/[[:space:]]+/_/g’

这里注意,rename 采用的是标准perl正则语法,所以无须将
加号转变为反斜杠加号 
即 + 不能修改为 +,否则替换失败。

还有几个好玩的例子:
比如统一在文件头部添加上 hello  
rename          ‘s/^/hello/’        *

统一把.html扩展名修改为 .htm 
rename          ‘s/.html$/.htm/’      *

统一在尾部追加 .zip后缀:
rename          ‘s/$/.zip/’      *

统一去掉.zip后缀:
rename          ‘s/.zip$//’      *

Ok ,rename就研究了这么多,暂时不知道如何在rename中引入动态变量,比如
$i++

我测试过 i=0;  rename -n “s/^.*$/$((++i))/”   * 
执行后i被自增了1,并非想我想像中那样,可以在每操作一个文件自增一,猜想可能是因为rename批量实现的,导致++i只计算一次!

-n 用来测试rename过程,并不直接运行,可以查看测试效果后,然后再运行。

++++++++++++++++++++++++++++++++++++++++++++++++++++++

1.rename命令批量修改文件名, 其实linux下可以使用别的办法来批量修改文件名,
不过rename实在太方便了

比如把所有的表为cdb1_* 修改为cdb_*的
在本目录下
只需要# rename ‘cdb1’ ‘cdb’ *

以前都是写个for循环来做…想想多傻啊, 呵呵

rename还有更多的功能, 建议man rename下

From:

2.批量更改文件名 rename

通过 man rename 命令可以得知,rename 命令其实是一个 Perl 脚本命令,
它专用于批量地给多文件重命名(rename multiple files)。

命令格式:
rename [ -v ] [ -n ] [ -f ]
perlexpr [ files ]
perlexpr 是一种 Perl 脚本格式的正则表达式。
参数:
-v, –verbose
Verbose: print names of files successfully renamed.
详细模式:打印成功更改的文件名列表
-n, –no-act
No Action: show what files would have been renamed.
测试模式:并不真正的执行命令,而只是显示哪些文件名应该怎么进行
更改,用于测试模式。
-f, –force
Force: overwrite existing files.
强制模式:在更改文件名,如果更改后的文件已经存在时覆盖已经存在
的文件。

rename
的典型应用:

0. 批量更改文件扩展名
$ ls
1.txt 2.txt 3.txt 4.txt
$ rename ‘s/.txt/.ext/’ *
$ ls
1.ext 2.ext 3.ext 4.ext

  1. 批量删除文件扩展名
    $ ls
    1.txt 2.txt 3.txt 4.txt
    $ rename ‘s/.txt//’ *
    $ ls
    1 2 3 4
  2. 批量添加文件扩展名
    $ ls
    1 2 3 4
    $ rename ‘s/$/.txt/’ *
    $ ls
    1.txt 2.txt 3.txt 4.txt
  3. 按自己的方式批量重命名文件
    $ ls
    1.ext 2.ext 3.ext 4.ext
    $ rename ‘s/(d)/第$1 章/’ *
    $ ls
    第 1 章.ext 第 2 章.ext 第 3 章.ext 第 4
    章.ext

方法1:把文件名拆分处理,可以任意修改文件名

find -name ‘*.log’ -printf %f\n|awk -F’.’ ‘{print $1}’|xargs -i{} mv
{}.log xiyun_{}.log

方法2:利用rename

一般的linux下的rename命令比较简单

rename ‘test’ ‘xiyun’ ‘*.log’

把文件名中的某部分字符串替换掉

ubuntu下的rename命令支持正则表达式,因此功能更强大。

方法3:直接利用find和xargs和mv,中间不用awk,这样只能添加后缀名,不能修改文件名。

来自: 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图