Edit: I should have pointed out originally, as I have now received feedback on this. This is NOT the best or optimal way of performing this task. I was trying to illustrate as many shell scripting principles as possible in terms of ‘if’, ‘for’, counters, etc, and how such a one liner has been put together. Perhaps I should have thought of a better way of illustrating such principles, but nevertheless, here it is!
Here’s a quick one liner, can’t think why anyone would ever have any use for it, but maybe the principle itself could be of use to someone! This will take a file containing listings of 16 digit numbers, i.e. 1234123412341234 and replace it with XXXXXXXXXXXX1234
Duly spaced and indented:
P=”"
ctr=0;
for I in `echo $I|grep -o .`; do
let ctr=$ctr+1;
if [ $ctr -gt 12 ]; then
P=${P}${I};
else
P=${P}”X”;
fi;
done;
echo $P|tr -d ‘\n’;
echo -ne “\n”;
done
Would love anyone to comment with variations.
Tags: bash, echo, grep, script, tr
I’d just do it with a regular expression…
wxs@rst wxs % cat foo
a
a111111111112222
1a11111111112222
1111111111112222
222222222223333
33333333333334444
wxs@rst wxs % sed -e ’s/^[0-9]\{12\}\([0-9]\{4\}\)$/XXXXXXXXXXXX\1/’ < foo
a
a111111111112222
1a11111111112222
XXXXXXXXXXXX2222
222222222223333
33333333333334444
wxs@rst wxs %
I’m with Wesley here. Why iterate with (poorly performing) bash, when you can use faster Perl Regular Expressions in a single command instead?
Using perl instead of sed, you can get the regex even shorter (and it’s platform-independent as sed takes different parameters on Linux and OSX for extended regular expressions).
Example here: http://pastebin.com/f12cc8612
How about this ?
$ echo “123456789″ | sed -r “s/^(.{0})(.{5})/\1XXXXX/”
Output:
XXXXX6789
http://unstableme.blogspot.com/2008/01/substitute-character-by-position-sed.html
// Jadu