1 """Helper class to quickly write a loop over all standard input files.
6 for line in fileinput.input():
9 This iterates over the lines of all files listed in sys.argv[1:],
10 defaulting to sys.stdin if the list is empty. If a filename is '-' it
11 is also replaced by sys.stdin. To specify an alternative list of
12 filenames, pass it as the argument to input(). A single file name is
15 Functions filename(), lineno() return the filename and cumulative line
16 number of the line that has just been read; filelineno() returns its
17 line number in the current file; isfirstline() returns true iff the
18 line just read is the first line of its file; isstdin() returns true
19 iff the line was read from sys.stdin. Function nextfile() closes the
20 current file so that the next iteration will read the first line from
21 the next file (if any); lines not read from the file will not count
22 towards the cumulative line count; the filename is not changed until
23 after the first line of the next file has been read. Function close()
26 Before any lines have been read, filename() returns None and both line
27 numbers are zero; nextfile() has no effect. After all lines have been
28 read, filename() and the line number functions return the values
29 pertaining to the last line read; nextfile() has no effect.
31 All files are opened in text mode. If an I/O error occurs during
32 opening or reading a file, the IOError exception is raised.
34 If sys.stdin is used more than once, the second and further use will
35 return no lines, except perhaps for interactive use, or if it has been
36 explicitly reset (e.g. using sys.stdin.seek(0)).
38 Empty files are opened and immediately closed; the only time their
39 presence in the list of filenames is noticeable at all is when the
40 last file opened is empty.
42 It is possible that the last line of a file doesn't end in a newline
43 character; otherwise lines are returned including the trailing
46 Class FileInput is the implementation; its methods filename(),
47 lineno(), fileline(), isfirstline(), isstdin(), nextfile() and close()
48 correspond to the functions in the module. In addition it has a
49 readline() method which returns the next input line, and a
50 __getitem__() method which implements the sequence behavior. The
51 sequence must be accessed in strictly sequential order; sequence
52 access and readline() cannot be mixed.
54 Optional in-place filtering: if the keyword argument inplace=1 is
55 passed to input() or to the FileInput constructor, the file is moved
56 to a backup file and standard output is directed to the input file.
57 This makes it possible to write a filter that rewrites its input file
58 in place. If the keyword argument backup=".<some extension>" is also
59 given, it specifies the extension for the backup file, and the backup
60 file remains around; by default, the extension is ".bak" and it is
61 deleted when the output file is closed. In-place filtering is
62 disabled when standard input is read. XXX The current implementation
63 does not work for MS-DOS 8+3 filesystems.
65 Performance: this module is unfortunately one of the slower ways of
66 processing large numbers of input lines. Nevertheless, a significant
67 speed-up has been obtained by using readlines(bufsize) instead of
68 readline(). A new keyword argument, bufsize=N, is present on the
69 input() function and the FileInput() class to override the default
72 XXX Possible additions:
74 - optional getopt argument processing
75 - specify open mode ('r' or 'rb')
78 - read(), read(size), even readlines()
84 __all__
= ["input","close","nextfile","filename","lineno","filelineno",
85 "isfirstline","isstdin","FileInput"]
89 DEFAULT_BUFSIZE
= 8*1024
91 def input(files
=None, inplace
=0, backup
="", bufsize
=0):
93 if _state
and _state
._file
:
94 raise RuntimeError, "input() already active"
95 _state
= FileInput(files
, inplace
, backup
, bufsize
)
107 raise RuntimeError, "no active input()"
108 return _state
.nextfile()
112 raise RuntimeError, "no active input()"
113 return _state
.filename()
117 raise RuntimeError, "no active input()"
118 return _state
.lineno()
122 raise RuntimeError, "no active input()"
123 return _state
.filelineno()
127 raise RuntimeError, "no active input()"
128 return _state
.isfirstline()
132 raise RuntimeError, "no active input()"
133 return _state
.isstdin()
137 def __init__(self
, files
=None, inplace
=0, backup
="", bufsize
=0):
138 if type(files
) == type(''):
148 self
._inplace
= inplace
149 self
._backup
= backup
150 self
._bufsize
= bufsize
or DEFAULT_BUFSIZE
151 self
._savestdout
= None
153 self
._filename
= None
158 self
._backupfilename
= None
169 def __getitem__(self
, i
):
171 line
= self
._buffer
[self
._bufindex
]
177 self
._filelineno
+= 1
179 if i
!= self
._lineno
:
180 raise RuntimeError, "accessing lines out of order"
181 line
= self
.readline()
183 raise IndexError, "end of input reached"
187 savestdout
= self
._savestdout
190 sys
.stdout
= savestdout
192 output
= self
._output
199 if file and not self
._isstdin
:
202 backupfilename
= self
._backupfilename
203 self
._backupfilename
= 0
204 if backupfilename
and not self
._backup
:
205 try: os
.unlink(backupfilename
)
214 line
= self
._buffer
[self
._bufindex
]
220 self
._filelineno
+= 1
225 self
._filename
= self
._files
[0]
226 self
._files
= self
._files
[1:]
230 self
._backupfilename
= 0
231 if self
._filename
== '-':
232 self
._filename
= '<stdin>'
233 self
._file
= sys
.stdin
237 self
._backupfilename
= (
238 self
._filename
+ (self
._backup
or ".bak"))
239 try: os
.unlink(self
._backupfilename
)
240 except os
.error
: pass
241 # The next few lines may raise IOError
242 os
.rename(self
._filename
, self
._backupfilename
)
243 self
._file
= open(self
._backupfilename
, "r")
245 perm
= os
.fstat(self
._file
.fileno())[stat
.ST_MODE
]
247 self
._output
= open(self
._filename
, "w")
249 fd
= os
.open(self
._filename
,
250 os
.O_CREAT | os
.O_WRONLY | os
.O_TRUNC
,
252 self
._output
= os
.fdopen(fd
, "w")
254 os
.chmod(self
._filename
, perm
)
257 self
._savestdout
= sys
.stdout
258 sys
.stdout
= self
._output
260 # This may raise IOError
261 self
._file
= open(self
._filename
, "r")
262 self
._buffer
= self
._file
.readlines(self
._bufsize
)
267 return self
.readline()
270 return self
._filename
275 def filelineno(self
):
276 return self
._filelineno
278 def isfirstline(self
):
279 return self
._filelineno
== 1
288 opts
, args
= getopt
.getopt(sys
.argv
[1:], "ib:")
290 if o
== '-i': inplace
= 1
291 if o
== '-b': backup
= a
292 for line
in input(args
, inplace
=inplace
, backup
=backup
):
293 if line
[-1:] == '\n': line
= line
[:-1]
294 if line
[-1:] == '\r': line
= line
[:-1]
295 print "%d: %s[%d]%s %s" % (lineno(), filename(), filelineno(),
296 isfirstline() and "*" or "", line
)
297 print "%d: %s[%d]" % (lineno(), filename(), filelineno())
299 if __name__
== '__main__':