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 by default, you can override this by
32
setting the mode parameter to input() or FileInput.__init__().
33
If an I/O error occurs during opening or reading a file, the IOError
36
If sys.stdin is used more than once, the second and further use will
37
return no lines, except perhaps for interactive use, or if it has been
38
explicitly reset (e.g. using sys.stdin.seek(0)).
40
Empty files are opened and immediately closed; the only time their
41
presence in the list of filenames is noticeable at all is when the
42
last file opened is empty.
44
It is possible that the last line of a file doesn't end in a newline
45
character; otherwise lines are returned including the trailing
48
Class FileInput is the implementation; its methods filename(),
49
lineno(), fileline(), isfirstline(), isstdin(), nextfile() and close()
50
correspond to the functions in the module. In addition it has a
51
readline() method which returns the next input line, and a
52
__getitem__() method which implements the sequence behavior. The
53
sequence must be accessed in strictly sequential order; sequence
54
access and readline() cannot be mixed.
56
Optional in-place filtering: if the keyword argument inplace=1 is
57
passed to input() or to the FileInput constructor, the file is moved
58
to a backup file and standard output is directed to the input file.
59
This makes it possible to write a filter that rewrites its input file
60
in place. If the keyword argument backup=".<some extension>" is also
61
given, it specifies the extension for the backup file, and the backup
62
file remains around; by default, the extension is ".bak" and it is
63
deleted when the output file is closed. In-place filtering is
64
disabled when standard input is read. XXX The current implementation
65
does not work for MS-DOS 8+3 filesystems.
67
Performance: this module is unfortunately one of the slower ways of
68
processing large numbers of input lines. Nevertheless, a significant
69
speed-up has been obtained by using readlines(bufsize) instead of
70
readline(). A new keyword argument, bufsize=N, is present on the
71
input() function and the FileInput() class to override the default
74
XXX Possible additions:
76
- optional getopt argument processing
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,
92
mode="r", openhook=None):
93
"""input([files[, inplace[, backup[, mode[, openhook]]]]])
95
Create an instance of the FileInput class. The instance will be used
96
as global state for the functions of this module, and is also returned
97
to use during iteration. The parameters to this function will be passed
98
along to the constructor of the FileInput class.
101
if _state and _state._file:
102
raise RuntimeError("input() already active")
103
_state = FileInput(files, inplace, backup, bufsize, mode, openhook)
107
"""Close the sequence."""
116
Close the current file so that the next iteration will read the first
117
line from the next file (if any); lines not read from the file will
118
not count towards the cumulative line count. The filename is not
119
changed until after the first line of the next file has been read.
120
Before the first line has been read, this function has no effect;
121
it cannot be used to skip the first file. After the last line of the
122
last file has been read, this function has no effect.
125
raise RuntimeError("no active input()")
126
return _state.nextfile()
130
Return the name of the file currently being read.
131
Before the first line has been read, returns None.
134
raise RuntimeError("no active input()")
135
return _state.filename()
139
Return the cumulative line number of the line that has just been read.
140
Before the first line has been read, returns 0. After the last line
141
of the last file has been read, returns the line number of that line.
144
raise RuntimeError("no active input()")
145
return _state.lineno()
149
Return the line number in the current file. Before the first line
150
has been read, returns 0. After the last line of the last file has
151
been read, returns the line number of that line within the file.
154
raise RuntimeError("no active input()")
155
return _state.filelineno()
159
Return the file number of the current file. When no file is currently
163
raise RuntimeError("no active input()")
164
return _state.fileno()
168
Returns true the line just read is the first line of its file,
169
otherwise returns false.
172
raise RuntimeError("no active input()")
173
return _state.isfirstline()
177
Returns true if the last line was read from sys.stdin,
178
otherwise returns false.
181
raise RuntimeError("no active input()")
182
return _state.isstdin()
185
"""class FileInput([files[, inplace[, backup[, mode[, openhook]]]]])
187
Class FileInput is the implementation of the module; its methods
188
filename(), lineno(), fileline(), isfirstline(), isstdin(), fileno(),
189
nextfile() and close() correspond to the functions of the same name
191
In addition it has a readline() method which returns the next
192
input line, and a __getitem__() method which implements the
193
sequence behavior. The sequence must be accessed in strictly
194
sequential order; random access and readline() cannot be mixed.
197
def __init__(self, files=None, inplace=0, backup="", bufsize=0,
198
mode="r", openhook=None):
199
if isinstance(files, str):
209
self._inplace = inplace
210
self._backup = backup
211
self._bufsize = bufsize or DEFAULT_BUFSIZE
212
self._savestdout = None
214
self._filename = None
218
self._isstdin = False
219
self._backupfilename = None
222
# restrict mode argument to reading modes
223
if mode not in ('r', 'rU', 'U', 'rb'):
224
raise ValueError("FileInput opening mode must be one of "
225
"'r', 'rU', 'U' and 'rb'")
227
if inplace and openhook:
228
raise ValueError("FileInput cannot use an opening hook in inplace mode")
229
elif openhook and not hasattr(openhook, '__call__'):
230
raise ValueError("FileInput openhook must be callable")
231
self._openhook = openhook
245
line = self._buffer[self._bufindex]
251
self._filelineno += 1
253
line = self.readline()
258
def __getitem__(self, i):
259
if i != self._lineno:
260
raise RuntimeError("accessing lines out of order")
262
return self.__next__()
263
except StopIteration:
264
raise IndexError("end of input reached")
267
savestdout = self._savestdout
270
sys.stdout = savestdout
272
output = self._output
279
if file and not self._isstdin:
282
backupfilename = self._backupfilename
283
self._backupfilename = 0
284
if backupfilename and not self._backup:
285
try: os.unlink(backupfilename)
288
self._isstdin = False
294
line = self._buffer[self._bufindex]
300
self._filelineno += 1
305
self._filename = self._files[0]
306
self._files = self._files[1:]
309
self._isstdin = False
310
self._backupfilename = 0
311
if self._filename == '-':
312
self._filename = '<stdin>'
313
self._file = sys.stdin
317
self._backupfilename = (
318
self._filename + (self._backup or ".bak"))
319
try: os.unlink(self._backupfilename)
320
except os.error: pass
321
# The next few lines may raise IOError
322
os.rename(self._filename, self._backupfilename)
323
self._file = open(self._backupfilename, self._mode)
325
perm = os.fstat(self._file.fileno()).st_mode
327
self._output = open(self._filename, "w")
329
mode = os.O_CREAT | os.O_WRONLY | os.O_TRUNC
330
if hasattr(os, 'O_BINARY'):
333
fd = os.open(self._filename, mode, perm)
334
self._output = os.fdopen(fd, "w")
336
if hasattr(os, 'chmod'):
337
os.chmod(self._filename, perm)
340
self._savestdout = sys.stdout
341
sys.stdout = self._output
343
# This may raise IOError
345
self._file = self._openhook(self._filename, self._mode)
347
self._file = open(self._filename, self._mode)
348
self._buffer = self._file.readlines(self._bufsize)
353
return self.readline()
356
return self._filename
361
def filelineno(self):
362
return self._filelineno
367
return self._file.fileno()
373
def isfirstline(self):
374
return self._filelineno == 1
380
def hook_compressed(filename, mode):
381
ext = os.path.splitext(filename)[1]
384
return gzip.open(filename, mode)
387
return bz2.BZ2File(filename, mode)
389
return open(filename, mode)
392
def hook_encoded(encoding):
394
def openhook(filename, mode):
395
return codecs.open(filename, mode, encoding)
403
opts, args = getopt.getopt(sys.argv[1:], "ib:")
405
if o == '-i': inplace = 1
406
if o == '-b': backup = a
407
for line in input(args, inplace=inplace, backup=backup):
408
if line[-1:] == '\n': line = line[:-1]
409
if line[-1:] == '\r': line = line[:-1]
410
print("%d: %s[%d]%s %s" % (lineno(), filename(), filelineno(),
411
isfirstline() and "*" or "", line))
412
print("%d: %s[%d]" % (lineno(), filename(), filelineno()))
414
if __name__ == '__main__':