As noted in the comments, the primary problem is that the shell variables $FT_LINE1
and $FT_LINE2
are not set correctly. You must ensure they are set to suitable values.
The exercise is convoluted and nasty. It also requires UUoC (Useless Use of cat
), but you can't help that.
There are several ways to do it. A first variant is:
# Set range of lines to print
FT_LINE1=3
FT_LINE2=9
cat /etc/passwd | # UUoC required by question
grep -v '^[[:space:]]*#' | # Non-comment lines
sed -e 's/:.*//' -e '1!n;d' | # Remove info after login name; print lines 2,4,6,8,...
rev | # Reverse each name
sort -rdf | # Sort in reverse dictionary order, case-insensitively
sed -n "${FT_LINE1},${FT_LINE2}p" | # Select lines in the range $FT_LINE1 to $FT_LINE2 inclusive
tr '
' ',' | # Convert newlines to commas
sed 's/,$/./' # Convert final comma to dot
This uses grep
, sed
, rev
, sort
and tr
. The grep | sed
part isn't entirely satisfactory, but line counting for lines 2, 4, 6, 8, … in sed
gets messy if it also tries to eliminate comments.
A second variant uses awk
twice. The first awk
ignores comment lines and for every second non-comment line, reverses the data in field one before printing it (combining the grep | sed | rev
sequence into one command). The second awk
concatenates the lines from the sort
into a comma-separated list and prints it with a dot at the end.
# Set range of lines to print
FT_LINE1=3
FT_LINE2=9
cat /etc/passwd |
awk -F:
'/^#/ { next }
{ if (++numout % 2 == 0)
{
out = ""
for (i = length($1); i > 0; i--)
out = out substr($1, i, 1)
print out
}
}
' |
sort -rdf |
awk -v line1="$FT_LINE1" -v line2="$FT_LINE2"
'NR >= line1 && NR <= line2 { out = out pad $1; pad = "," }
END { print out "." }
'
On my Mac, the output from the two scripts is the same — YMWV (Your Mileage Will Vary because your list of users will be different):
www_,vamalc_,toorsmvc_,toor,tocevod_,tnegaevitpac_,svc_.
www_,vamalc_,toorsmvc_,toor,tocevod_,tnegaevitpac_,svc_.
Given GNU Awk, it is probably possible to do the whole job in a single Awk script; it has built-in sorting functions. However, case-insensitive string comparison does not seem to be one of the built-in options, so it gets fiddly. Hence, I kept the external sort
command. Where the first script has print out
, a sorting script would use saved[i++] = out
. The END
block would then sort the saved
array (probably using a custom function to sort case-insensitively), and then select elements from line1 through line2 of the sorted array, concatenating them and printing the result, rather like the second script does anyway.