The substr function takes between two and four arguments. With two arguments, a character string and a numeric offset, it returns the piece of the character string starting at the offset and continuing to the end of the original string. Recall that offsets in perl are zero-based. An optional third argument can be provided to specify a length for the desired substring, if the entire string from the offset on is not desired. Finally, a fourth optional argument specifies a replacement string to put into the original string, in place of the substring which is extracted. Without a fourth argument, the original string is left unchanged. With the fourth argument, substr can be used with character strings in the same way splice can be used with arrays (Section 4.4).
Suppose we wish to write a program which will translate the permissions displayed with the UNIX ``ls -l'' command into the numerical form which the chmod function expects. The output from this command looks like:
-rw------- 1 spector staff 90 Mar 2 15:31 i.pl -rwx--x--x 1 spector staff 49 Dec 22 11:35 in.pl -rwx--x--x 1 spector staff 194 Feb 21 11:18 io.pl -rwx--x--x 1 spector staff 79 Feb 29 11:37 n.plStarting at the second character in each line, there are three blocks of three letters each, representing read, write and execute access, respectively, for the user, group members and others. The following program reads the output of the ls -l command, and converts this information into a numerical mode:
%values = ('-'=>0,'r'=>4,'w'=>2,'x'=>1); open(LS,"ls -l|") || die "Couldn't run ls command"; while(<LS>){ chomp; ($file = substr($_,54)) =~ s/ +$//; $perms = substr($_,1,9); foreach $i (0..2){ $start = $i * 3; $tmp = 0; foreach $j (0..2){ $tmp += $values{substr($perms,$start + $j,1)}; } $mode[$i] = $tmp; } printf("$file: %s\n",join("",@mode)); }
The substr function can also be used on the left-hand side of an assignment statement, as an alternative to calling the function with a fourth argument. The substring specified on the left-hand side will then be replaced in the original string with the string on the right-hand side of the assignment statement.
$str = "Dear John,"; substr($str,5,4) = "Harry"; print $str; # prints Dear Harry,As this example shows, the right-hand side replacement string needn't be the same length as the substring specified on the left-hand side of the assignment statement.