Diamond Operator
Two angle brackets. Empty:The diamond operator. Also called the null filehandle. Every Perl scripter uses it, often without knowing its name.<>
It reads from files or STDIN, magically.
Part 1: THE MAGIC
Run this script three ways:while (<>) { print; }
The diamond figures out what you meant. Files on command line? Read those. Nothing? Read STDIN. It just works.perl script.pl file1.txt file2.txt # Reads both files cat data.txt | perl script.pl # Reads from pipe perl script.pl # Reads from keyboard
Part 2: HOW IT WORKS
The diamond reads from @ARGV if it has files, otherwise from STDIN.Step by step:
It's the behavior that makes Unix filter programs work:1. Check @ARGV 2. If files exist, open and read the first one 3. When exhausted, move to the next file in @ARGV 4. If @ARGV is empty, read from STDIN
Same command, different input sources.grep pattern file.txt # Read from file cat file.txt | grep pattern # Read from pipe
.--. |o_o | |:_/ | // \ \ (| | ) /'\_ _/`\ \___)=(___/
Part 3: THE -n AND -p SWITCHES
The diamond is why -n and -p work:This wraps your code in:perl -ne 'print if /pattern/' file.txt
The diamond handles the file automatically.while (<>) { print if /pattern/; }
Part 4: MULTIPLE FILES
Process many files seamlessly:$ARGV contains the current filename. The diamond reads each file in sequence.perl -ne 'print "$ARGV: $_"' *.txt
Output:
file1.txt: first line of file1 file1.txt: second line of file1 file2.txt: first line of file2 ...
Part 5: LINE NUMBERS
$. is the line number:But here's a gotcha: $. doesn't reset between files!while (<>) { print "$.: $_"; }
If file1.txt has 10 lines, file2.txt starts at line 11.perl -ne 'print "$.: $_"' file1.txt file2.txt
To reset, close ARGV explicitly:
while (<>) { print "$ARGV:$.: $_"; } continue { close ARGV if eof; # Reset $. for next file }
Part 6: MODIFYING @ARGV
You can manipulate @ARGV before the loop:Or add files programmatically:# Only process .log files @ARGV = grep { /\.log$/ } @ARGV; while (<>) { # ... }
Default to syslog if no files given.push @ARGV, '/var/log/syslog' unless @ARGV; while (<>) { # ... }
Part 7: THE DASH TRICK
A single dash means STDIN:This reads file1, then STDIN, then file2. Useful for mixing file input with piped data.perl script.pl file1.txt - file2.txt
echo "injected line" | perl script.pl before.txt - after.txt
Part 8: IN-PLACE EDITING
The diamond enables -i (in-place editing):This:perl -i.bak -pe 's/old/new/g' file.txt
The diamond is doing all the file handling.1. Reads file.txt via diamond 2. Processes each line 3. Writes back to the same file 4. Saves original as file.txt.bak
Part 9: READING ALL AT ONCE
Slurp mode reads entire file:Or multiple files into an array:local $/ = undef; # Unset record separator my $content = <>; # Read entire file(s)
Warning: memory-intensive for large files.my @all_lines = <>; # All lines from all files
Part 10: EXPLICIT FILEHANDLES
Diamond reads from ARGV implicitly. For explicit control:Or the old-school bareword:open my $fh, '<', 'file.txt' or die; while (<$fh>) { # ... }
Diamond is for when you want the magic.open FH, '<', 'file.txt' or die; while (<FH>) { # ... }
Part 11: THE SECURITY PROBLEM
Here's the dark side. The diamond uses two-argument open:Two-argument open interprets special characters:while (<>) # Internally: open(ARGV, $ARGV[0])
This doesn't read a file called "rm -rf / |". It EXECUTES that command and reads its output.perl script.pl 'rm -rf / |'
Dangerous if @ARGV comes from untrusted input.
Fix: use the double diamond (next tutorial) or validate @ARGV.
Part 12: USEFUL PATTERNS
Count lines in multiple files:Search and report with filenames:my $total = 0; while (<>) { $total++; } print "Total lines: $total\n";
Concatenate files with headers:while (<>) { print "$ARGV:$.: $_" if /pattern/; } continue { close ARGV if eof; }
my $current = ''; while (<>) { if ($ARGV ne $current) { print "=** $ARGV **=\n"; $current = $ARGV; } print; }
Part 13: THE NAME
Look at it:It's a diamond shape. Or an empty box. Or angle brackets with nothing inside.<>
"Null filehandle" is the technical name. "Diamond operator" is what everyone calls it.
The angles point outward like rays of magic, pulling input from wherever it needs to come from.
<> / \ / \ < > \ / \ / \/ Magic input since Perl 1
Created By: Wildcard Wizard. Copyright 2026