📄 ch09_10.htm
字号:
<HTML><HEAD><TITLE>Recipe 9.9. Renaming Files (Perl Cookbook)</TITLE><METANAME="DC.title"CONTENT="Perl Cookbook"><METANAME="DC.creator"CONTENT="Tom Christiansen & Nathan Torkington"><METANAME="DC.publisher"CONTENT="O'Reilly & Associates, Inc."><METANAME="DC.date"CONTENT="1999-07-02T01:39:20Z"><METANAME="DC.type"CONTENT="Text.Monograph"><METANAME="DC.format"CONTENT="text/html"SCHEME="MIME"><METANAME="DC.source"CONTENT="1-56592-243-3"SCHEME="ISBN"><METANAME="DC.language"CONTENT="en-US"><METANAME="generator"CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"><LINKREV="made"HREF="mailto:online-books@oreilly.com"TITLE="Online Books Comments"><LINKREL="up"HREF="ch09_01.htm"TITLE="9. Directories"><LINKREL="prev"HREF="ch09_09.htm"TITLE="9.8. Removing a Directory and Its Contents"><LINKREL="next"HREF="ch09_11.htm"TITLE="9.10. Splitting a Filename into Its Component Parts"></HEAD><BODYBGCOLOR="#FFFFFF"><img alt="Book Home" border="0" src="gifs/smbanner.gif" usemap="#banner-map" /><map name="banner-map"><area shape="rect" coords="1,-2,616,66" href="index.htm" alt="Perl Cookbook"><area shape="rect" coords="629,-11,726,25" href="jobjects/fsearch.htm" alt="Search this book" /></map><div class="navbar"><p><TABLEWIDTH="684"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch09_09.htm"TITLE="9.8. Removing a Directory and Its Contents"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 9.8. Removing a Directory and Its Contents"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><B><FONTFACE="ARIEL,HELVETICA,HELV,SANSERIF"SIZE="-1"><ACLASS="chapter"REL="up"HREF="ch09_01.htm"TITLE="9. Directories"></A></FONT></B></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch09_11.htm"TITLE="9.10. Splitting a Filename into Its Component Parts"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 9.10. Splitting a Filename into Its Component Parts"BORDER="0"></A></TD></TR></TABLE></DIV><DIVCLASS="sect1"><H2CLASS="sect1"><ACLASS="title"NAME="ch09-60164">9.9. Renaming Files</A></H2><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch09-pgfId-944">Problem<ACLASS="indexterm"NAME="ch09-idx-1000004434-0"></A><ACLASS="indexterm"NAME="ch09-idx-1000004434-1"></A><ACLASS="indexterm"NAME="ch09-idx-1000004434-2"></A></A></H3><PCLASS="para">You have a lot of files whose names you want to change.</P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch09-pgfId-950">Solution</A></H3><PCLASS="para">Use a <CODECLASS="literal">foreach</CODE> loop and the <CODECLASS="literal">rename</CODE> function:</P><PRECLASS="programlisting">foreach $file (@NAMES) { my $newname = $file; # change $newname rename($file, $newname) or warn "Couldn't rename $file to $newname: $!\n";}</PRE></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch09-pgfId-1000004700">Discussion</A></H3><PCLASS="para">This is straightforward. <CODECLASS="literal">rename</CODE> takes two arguments. The first is the filename to change, and the second is its new name. Perl's <CODECLASS="literal">rename</CODE> is a front end to the operating system's rename system call, which typically won't let you rename files across filesystem boundaries.</P><PCLASS="para">A small change turns this into a generic <CODECLASS="literal">rename</CODE><ACLASS="indexterm"NAME="ch09-idx-1000004438-0"></A> script, such as the one by Larry Wall shown in <ACLASS="xref"HREF="ch09_10.htm#ch09-40514"TITLE="rename">Example 9.5</A>.</P><DIVCLASS="example"><H4CLASS="example"><ACLASS="title"NAME="ch09-40514">Example 9.5: rename</A></H4><PRECLASS="programlisting">#!/usr/bin/perl -w# rename - Larry's filename fixer$op = shift or die "Usage: rename expr [files]\n";chomp(@ARGV = <STDIN>) unless @ARGV;for (@ARGV) { $was = $_; eval $op; die $@ if $@; rename($was,$_) unless $was eq $_;}</PRE></DIV><PCLASS="para">This script's first argument is Perl code that alters the filename (stored in <CODECLASS="literal">$_ </CODE>) to reflect how you want the file renamed. It can do this because it uses an <CODECLASS="literal">eval</CODE> to do the hard work. It also skips <CODECLASS="literal">rename</CODE> calls when the filename is untouched. This lets you simply use wildcards like <CODECLASS="literal">rename</CODE> <CODECLASS="literal">EXPR</CODE> <CODECLASS="literal">*</CODE> instead of making long lists of filenames.</P><PCLASS="para">Here are five examples of calling the <EMCLASS="emphasis">rename</EM> program from your shell:</P><PRECLASS="programlisting">% rename 's/\.orig$//' *.orig% rename 'tr/A-Z/a-z/ unless /^Make/' *% rename '$_ .= ".bad"' *.f% rename 'print "$_: "; s/foo/bar/ if <STDIN> =~ /^y/i' *% find /tmp -name '*~' -print | rename 's/^(.+)~$/.#$1/'</PRE><PCLASS="para">The first shell command removes a trailing <CODECLASS="literal">".orig"</CODE> from each filename.</P><PCLASS="para">The second converts uppercase to lowercase. Because a translation is used rather than the <CODECLASS="literal">lc</CODE> function, this conversion won't be locale-aware. To fix that, you'd have to write:</P><PRECLASS="programlisting">% rename 'use locale; $_ = lc($_) unless /^Make/' *</PRE><PCLASS="para">The third appends <CODECLASS="literal">".bad"</CODE> to each Fortran file ending in <CODECLASS="literal">".f"</CODE>, something a lot of us have wanted to do for a long time.</P><PCLASS="para">The fourth prompts the user for the change. Each file's name is printed to standard output and a response is read from standard input. If the user types something starting with a <CODECLASS="literal">"y"</CODE> or <CODECLASS="literal">"Y"</CODE>, any <CODECLASS="literal">"foo"</CODE> in the filename is changed to <CODECLASS="literal">"bar"</CODE>.</P><PCLASS="para">The fifth uses <EMCLASS="emphasis">find</EM> to locate files in <CODECLASS="literal">/tmp</CODE> that end with a tilde. It renames these so that instead of ending with a tilde, they start with a dot and a pound sign. In effect, this switches between two common conventions for backup files.</P><PCLASS="para">The <EMCLASS="emphasis">rename</EM> script exemplifies the powerful Unix tool-and-filter philosophy. Even though we could have created a dedicated command to do the lowercase conversion, it's nearly as easy to write a flexible, reusable tool by embedding an <CODECLASS="literal">eval</CODE>. By allowing the filenames to be read from standard input, we don't have to build in the recursive directory walk. Instead, we just use <EMCLASS="emphasis">find</EM>, which performs this function well. There's no reason to recreate the wheel, although using File::Find we could have.<ACLASS="indexterm"NAME="ch09-idx-1000004429-0"></A><ACLASS="indexterm"NAME="ch09-idx-1000004429-1"></A><ACLASS="indexterm"NAME="ch09-idx-1000004429-2"></A></P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch09-pgfId-1022">See Also</A></H3><PCLASS="para">The <CODECLASS="literal">rename</CODE> function in <ICLASS="filename">perlfunc </I>(1) and in <ACLASS="olink"HREF="../prog/ch03_01.htm">Chapter 3</A> of <ACLASS="citetitle"HREF="../prog/index.htm"TITLE="Programming Perl"><CITECLASS="citetitle">Programming Perl</CITE></A>; your system's <ICLASS="filename">mv </I>(1) and <ICLASS="filename">rename</I> (2) manpages; the documentation for the standard File::Find module (also in <ACLASS="olink"HREF="../prog/ch07_01.htm">Chapter 7</A> of <ACLASS="citetitle"HREF="../prog/index.htm"TITLE="Programming Perl"><CITECLASS="citetitle">Programming Perl</CITE></A>)</P></DIV></DIV><DIVCLASS="htmlnav"><P></P><HRALIGN="LEFT"WIDTH="684"TITLE="footer"><TABLEWIDTH="684"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch09_09.htm"TITLE="9.8. Removing a Directory and Its Contents"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 9.8. Removing a Directory and Its Contents"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><ACLASS="book"HREF="index.htm"TITLE="Perl Cookbook"><IMGSRC="../gifs/txthome.gif"ALT="Perl Cookbook"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch09_11.htm"TITLE="9.10. Splitting a Filename into Its Component Parts"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 9.10. Splitting a Filename into Its Component Parts"BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228">9.8. Removing a Directory and Its Contents</TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><ACLASS="index"HREF="index/index.htm"TITLE="Book Index"><IMGSRC="../gifs/index.gif"ALT="Book Index"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228">9.10. Splitting a Filename into Its Component Parts</TD></TR></TABLE><HRALIGN="LEFT"WIDTH="684"TITLE="footer"><FONTSIZE="-1"></DIV<!-- LIBRARY NAV BAR --> <img src="../gifs/smnavbar.gif" usemap="#library-map" border="0" alt="Library Navigation Links"><p> <a href="copyrght.htm">Copyright © 2002</a> O'Reilly & Associates. All rights reserved.</font> </p> <map name="library-map"> <area shape="rect" coords="1,0,85,94" href="../index.htm"><area shape="rect" coords="86,1,178,103" href="../lwp/index.htm"><area shape="rect" coords="180,0,265,103" href="../lperl/index.htm"><area shape="rect" coords="267,0,353,105" href="../perlnut/index.htm"><area shape="rect" coords="354,1,446,115" href="../prog/index.htm"><area shape="rect" coords="448,0,526,132" href="../tk/index.htm"><area shape="rect" coords="528,1,615,119" href="../cookbook/index.htm"><area shape="rect" coords="617,0,690,135" href="../pxml/index.htm"></map> </BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -