#!/usr/bin/perl # censor_passwd use warnings; use strict; my $passwd = 'hide_me'; my $replacement = 'removed'; # Used to check if the start of the password # is at the end of the read data. The returned # regexp will match 0 characters if not. # For efficiency, it expects the data to be # "reverse"d. my $partial_re = do { my $r = reduce { "(?:$a$b)?" } '', reverse map quotemeta, map /(.)/g, $passwd; qr/$r/ }; binmode(STDIN); binmode(STDOUT); $| = 1; my $buf = ''; for (;;) { my $rv = sysread(STDIN, $buf, 4096, length($buf)); defined $rv or die("Unable to read from STDIN: $!\n"); $rv or last; for (;;) { my $pos = index($buf, $passwd); last if $pos < 0; substr($buf, $pos, length($passwd), $replacement); print(substr($buf, 0, $pos+length($replacement), '')); } reverse($buf) =~ /^$partial_re/; print(substr($buf, 0, length($buf)-$+[0], '')); } print($buf);