Maybe the following will help you get what you need. It was written and tested using a Korn shell, but will work with any shell that understands basic POSIX required parameter expansions.
If you invoke this script with not operands, it will try to update a file named SAMPLE.txt
. If you invoke it with an operand, it will use the 1st operand as the pathname of the file to be updated.
#!/bin/ksh
# Get name of file to be processed:
INFILE=${1:-SAMPLE.txt}
OUTFILE="$INFILE.new"
# Convert the input file to a DOS formatted text file by completing the last
# input line (in case the last input line is incomplete..
printf '\r\n' >> "$INFILE"
# Use awk to search for and, if found, replace strings of asterisks in two
# locations on each line to strings of zeroes, and log any changes made.
# Delete blank lines in case the last input line was complete and we added an
# extraneous, empty, DOS format line.
awk -v OUTFILE="$OUTFILE" '
BEGIN { logfmt = "Fix applied: Line:%d, Offset:%d, Customer:%s\n"
spot[++ns] = 1050
spot[++ns] = 1249
}
/^[[:blank:]]*\r*$/ {
# Skip blank lines (with DOS or UNIX line terminators).
next
}
{ # Uncomment next line to change line terminators from DOS to UNIX.
# sub(/\r$/, "")
# Search the specified spots in each input line for 10 asterisks...
for(i = 1; i <= ns; i++)
if(substr($0, spot, 10) == "**********") {
# and when found, change them to zeros...
$0 = substr($0, 1, spot - 1) "0000000000" \
substr($0, spot + 10)
# and log the cange made.
printf(logfmt, NR, spot, substr($0, 1, 10))
}
# Copy the (possibly updated) input line to the output file.
print > OUTFILE
}' "$INFILE" && cp "$OUTFILE" "$INFILE" && rm -f "$OUTFILE"
# If the conversion succeeded, the above line replaces the contents of the
# input file (to avoid breaking any links to the input file), and if the copy
# succeeds removes the temp file holding the updated input.
If someone else wants to try this on a Solaris/SunOS system, change awk
in the script to /usr/xpg4/bin/awk
( nawk
won't work for this script).
With the SAMPLE.txt
file you provided as an input file, the awk
output is:
Fix applied: Line:13, Offset:1249, Customer:2y1023300
Fix applied: Line:33, Offset:1050, Customer:2a4323413
Fix applied: Line:34, Offset:1050, Customer:2a4323413
Fix applied: Line:41, Offset:1050, Customer:2a5133020
Fix applied: Line:45, Offset:1050, Customer:2a5203011
Fix applied: Line:46, Offset:1050, Customer:2a5203011
Fix applied: Line:49, Offset:1050, Customer:2a5231320
and the spots indicated above in SAMPLE.txt
are changed from **********
to 0000000000
, and a DOS <CR><NL> is added to the end of SAMPLE.txt
to complete the incomplete line.
And, if you uncomment the line shown in red in the script, it will convert DOS format lines in the input file into UNIX format lines.