⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch09_06.htm

📁 By Tom Christiansen and Nathan Torkington ISBN 1-56592-243-3 First Edition, published August 1998
💻 HTM
字号:
<HTML><HEAD><TITLE>Recipe 9.5. Processing All Files in a Directory (Perl Cookbook)</TITLE><METANAME="DC.title"CONTENT="Perl Cookbook"><METANAME="DC.creator"CONTENT="Tom Christiansen &amp; Nathan Torkington"><METANAME="DC.publisher"CONTENT="O'Reilly &amp; Associates, Inc."><METANAME="DC.date"CONTENT="1999-07-02T01:39:11Z"><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_05.htm"TITLE="9.4. Recognizing Two Names for the Same File"><LINKREL="next"HREF="ch09_07.htm"TITLE="9.6. Globbing, or Getting a List of Filenames Matching a Pattern"></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_05.htm"TITLE="9.4. Recognizing Two Names for the Same File"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 9.4. Recognizing Two Names for the Same File"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_07.htm"TITLE="9.6. Globbing, or Getting a List of Filenames Matching a Pattern"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 9.6. Globbing, or Getting a List of Filenames Matching a Pattern"BORDER="0"></A></TD></TR></TABLE></DIV><DIVCLASS="sect1"><H2CLASS="sect1"><ACLASS="title"NAME="ch09-chap09_processing_0">9.5. Processing All Files in a Directory</A></H2><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch09-pgfId-1000005078">Problem<ACLASS="indexterm"NAME="ch09-idx-1000005077-0"></A><ACLASS="indexterm"NAME="ch09-idx-1000005077-1"></A></A></H3><PCLASS="para">You want to do something to each file in a particular directory.</P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch09-pgfId-544">Solution</A></H3><PCLASS="para">Use <CODECLASS="literal">opendir</CODE><ACLASS="indexterm"NAME="ch09-idx-1000004383-0"></A><ACLASS="indexterm"NAME="ch09-idx-1000004383-1"></A> to open the directory and then <CODECLASS="literal">readdir</CODE> to retrieve every filename:</P><PRECLASS="programlisting">opendir(DIR, $dirname) or die &quot;can't opendir $dirname: $!&quot;;while (defined($file = readdir(DIR))) {    # do something with &quot;$dirname/$file&quot;}closedir(DIR);</PRE></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch09-pgfId-560">Discussion</A></H3><PCLASS="para">The <CODECLASS="literal">opendir</CODE>, <CODECLASS="literal">readdir</CODE>, and <CODECLASS="literal">closedir</CODE> functions operate on directories as <CODECLASS="literal">open</CODE>, &lt; &gt;, and <CODECLASS="literal">close</CODE> operate on files. Both use handles, but the directory handles used by <CODECLASS="literal">opendir</CODE> and friends are different from the file handles used by <CODECLASS="literal">open</CODE> and friends. In particular, you can't use &lt; &gt; on a directory handle.</P><PCLASS="para">In scalar context, <CODECLASS="literal">readdir</CODE> returns the next filename in the directory until it reaches the end of the directory when it returns <CODECLASS="literal">undef</CODE>. In list context it returns the rest of the filenames in the directory or an empty list if there were no files left. As explained in the Introduction, the filenames returned by <CODECLASS="literal">readdir</CODE> do not include the directory name. When you work with the filenames returned by <CODECLASS="literal">readdir</CODE>, you must either move to the right directory first or prepend the directory to the filename.</P><PCLASS="para">This shows one way of prepending:</P><PRECLASS="programlisting">$dir = &quot;/usr/local/bin&quot;;print &quot;Text files in $dir are:\n&quot;;opendir(BIN, $dir) or die &quot;Can't open $dir: $!&quot;;while( defined ($file = readdir BIN) ) {    print &quot;$file\n&quot; if -T &quot;$dir/$file&quot;;}closedir(BIN);</PRE><PCLASS="para">We test <CODECLASS="literal">$file</CODE> with <CODECLASS="literal">defined</CODE> because simply saying <CODECLASS="literal">while</CODE> <CODECLASS="literal">($file</CODE> <CODECLASS="literal">=</CODE> <CODECLASS="literal">readdir</CODE> <CODECLASS="literal">BIN)</CODE> would only be testing truth and not definedness. Although the loop would end when <CODECLASS="literal">readdir</CODE> ran out of files to return, it would also end prematurely if a file had the name &quot;<CODECLASS="literal">0&quot;</CODE>.</P><PCLASS="para">The <CODECLASS="literal">readdir</CODE> function will return the special directories <CODECLASS="literal">&quot;.&quot;</CODE> (the directory itself) and <CODECLASS="literal">&quot;..&quot;</CODE> (the parent of the directory). Most people skip the files with code like:</P><PRECLASS="programlisting">while ( defined ($file = readdir BIN) ) {    next if $file =~ /^\.\.?$/;     # skip . and ..    # ...}</PRE><PCLASS="para">Like filehandles, directory handles are per-package constructs. Further, you have two ways of getting a local <ACLASS="indexterm"NAME="ch09-idx-1000006155-0"></A>directory handle: use <CODECLASS="literal">local</CODE> <CODECLASS="literal">*DIRHANDLE</CODE> or use an object module (see <ACLASS="xref"HREF="ch07_17.htm"TITLE="Storing Filehandles in Variables">Recipe 7.16</A>). The appropriate module in this case is <CODECLASS="literal">DirHandle</CODE>. The following code uses DirHandle and produces a sorted list of plain files that aren't dotfiles (that is, whose names don't begin with a <CODECLASS="literal">&quot;.&quot;</CODE>):</P><PRECLASS="programlisting">use DirHandle;sub plainfiles {   my $dir = shift;   my $dh = DirHandle-&gt;new($dir)   or die &quot;can't opendir $dir: $!&quot;;   return sort                     # sort pathnames          grep {    -f     }       # choose only &quot;plain&quot; files          map  { &quot;$dir/$_&quot; }       # create full paths          grep {  !/^\./   }       # filter out dot files          $dh-&gt;<CODECLASS="literal">read()</CODE>;             # read all entries}</PRE><PCLASS="para">DirHandle's <CODECLASS="literal">read</CODE> method behaves just like <CODECLASS="literal">readdir</CODE>, returning the rest of the filenames. The bottom <CODECLASS="literal">grep</CODE> only returns those that don't begin with a period. The <CODECLASS="literal">map</CODE> turns the filenames returned by <CODECLASS="literal">read</CODE> into fully qualified filenames, and the top <CODECLASS="literal">grep</CODE> filters out directories, links, etc. The resulting list is then <CODECLASS="literal">sort</CODE>ed and returned.</P><PCLASS="para">In addition to <CODECLASS="literal">readdir</CODE>, there's also <CODECLASS="literal">rewinddir</CODE><ACLASS="indexterm"NAME="ch09-idx-1000004389-0"></A><ACLASS="indexterm"NAME="ch09-idx-1000004389-1"></A> (to move the directory handle back to the start of the filename list), <CODECLASS="literal">seekdir</CODE> (to move to a specific offset in the list), and <CODECLASS="literal">telldir</CODE> (to find out how far from the start of the list you are).<ACLASS="indexterm"NAME="ch09-idx-1000004385-0"></A><ACLASS="indexterm"NAME="ch09-idx-1000004385-1"></A></P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch09-pgfId-624">See Also</A></H3><PCLASS="para">The <CODECLASS="literal">closedir</CODE>, <CODECLASS="literal">opendir</CODE>, <CODECLASS="literal">readdir</CODE>, <CODECLASS="literal">rewinddir</CODE>, <CODECLASS="literal">seekdir</CODE>, and <CODECLASS="literal">telldir</CODE> functions 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>; documentation for the standard DirHandle 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_05.htm"TITLE="9.4. Recognizing Two Names for the Same File"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 9.4. Recognizing Two Names for the Same File"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_07.htm"TITLE="9.6. Globbing, or Getting a List of Filenames Matching a Pattern"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 9.6. Globbing, or Getting a List of Filenames Matching a Pattern"BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228">9.4. Recognizing Two Names for the Same File</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.6. Globbing, or Getting a List of Filenames Matching a Pattern</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 &copy; 2002</a> O'Reilly &amp; 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 + -