The fileinput module processes multiple files like Unix text tools. Iterate through files from command line args or stdin seamlessly.

Basic Usage

import fileinput
 
# Process files from command line args (or stdin)
for line in fileinput.input():
    print(line, end='')
 
# python script.py file1.txt file2.txt
# Or: cat data.txt | python script.py

Specify Files Explicitly

import fileinput
 
files = ['file1.txt', 'file2.txt', 'file3.txt']
 
for line in fileinput.input(files):
    print(line, end='')

Track Current File and Line

import fileinput
 
for line in fileinput.input():
    # Current filename
    filename = fileinput.filename()
    
    # Line number in current file
    lineno = fileinput.filelineno()
    
    # Total line number across all files
    total_lineno = fileinput.lineno()
    
    # First line of a new file?
    if fileinput.isfirstline():
        print(f"\n=== {filename} ===")
    
    print(f"{lineno}: {line}", end='')

In-Place Editing

Edit files directly like sed -i:

import fileinput
 
# Replace all occurrences
for line in fileinput.input('config.txt', inplace=True):
    # stdout goes to the file
    print(line.replace('old', 'new'), end='')

With backup:

import fileinput
 
for line in fileinput.input('data.txt', inplace=True, backup='.bak'):
    print(line.upper(), end='')
# Original saved as data.txt.bak

Context Manager

import fileinput
 
with fileinput.input(files) as f:
    for line in f:
        if f.isfirstline():
            print(f"\n--- {f.filename()} ---")
        print(line, end='')

FileInput Class

For more control:

import fileinput
 
fi = fileinput.FileInput(
    files=['a.txt', 'b.txt'],
    mode='r',
    openhook=fileinput.hook_encoded('utf-8')
)
 
try:
    for line in fi:
        print(f"{fi.filename()}:{fi.filelineno()}: {line}", end='')
finally:
    fi.close()

Handle Encoding

import fileinput
 
# UTF-8 encoded files
for line in fileinput.input(
    openhook=fileinput.hook_encoded('utf-8')
):
    print(line, end='')
 
# Compressed files
for line in fileinput.input(
    openhook=fileinput.hook_compressed
):
    print(line, end='')

Practical Examples

grep-like Tool

#!/usr/bin/env python3
import fileinput
import sys
import re
 
pattern = sys.argv[1]
files = sys.argv[2:] or ['-']  # stdin if no files
 
for line in fileinput.input(files):
    if re.search(pattern, line):
        print(f"{fileinput.filename()}:{fileinput.filelineno()}: {line}", end='')

Line Numbers

#!/usr/bin/env python3
import fileinput
 
for line in fileinput.input():
    print(f"{fileinput.lineno():6d}  {line}", end='')

Find and Replace

#!/usr/bin/env python3
import fileinput
import sys
 
old, new = sys.argv[1], sys.argv[2]
files = sys.argv[3:]
 
for line in fileinput.input(files, inplace=True, backup='.bak'):
    print(line.replace(old, new), end='')

Add Header to Files

import fileinput
 
header = "# Auto-generated file\n"
 
for line in fileinput.input(inplace=True, backup='.bak'):
    if fileinput.isfirstline():
        print(header, end='')
    print(line, end='')

Count Lines Per File

import fileinput
 
current_file = None
line_count = 0
 
for line in fileinput.input():
    if fileinput.filename() != current_file:
        if current_file:
            print(f"{current_file}: {line_count} lines")
        current_file = fileinput.filename()
        line_count = 0
    line_count += 1
 
if current_file:
    print(f"{current_file}: {line_count} lines")

Process Specific Lines

import fileinput
 
for line in fileinput.input():
    lineno = fileinput.filelineno()
    
    # Skip comments and empty lines
    if line.startswith('#') or not line.strip():
        continue
    
    # Process only first 10 lines of each file
    if lineno > 10:
        fileinput.nextfile()
        continue
    
    print(line, end='')

Key Functions

import fileinput
 
# Start processing
fileinput.input(files=None, inplace=False, backup='')
 
# During iteration
fileinput.filename()      # Current file name
fileinput.lineno()        # Total line number
fileinput.filelineno()    # Line number in current file
fileinput.isfirstline()   # Is first line of file?
fileinput.isstdin()       # Reading from stdin?
 
# Control
fileinput.nextfile()      # Skip to next file
fileinput.close()         # Close all

Quick Reference

import fileinput
 
# Basic iteration
for line in fileinput.input():
    process(line)
 
# With options
for line in fileinput.input(
    files=['a.txt', 'b.txt'],  # Files to process
    inplace=True,               # Edit in place
    backup='.bak',              # Backup extension
    mode='r',                   # Open mode
    openhook=None,              # Custom opener
):
    print(modified(line), end='')
 
# Track position
fileinput.filename()     # Current file
fileinput.filelineno()   # Line in current file
fileinput.lineno()       # Total lines
fileinput.isfirstline()  # First line?

fileinput makes Python scripts work like Unix text utilities. Pipe data in, process multiple files, or edit in place—all with simple iteration.

React to this post: