1

I need a help in the shell scripting processing the file. The script should read each file in the path and replace the string in each row.

It should read each line and replace the 7th column with XXXX mentioned in the sample output. Any help in appreciated.

Input file data

"2013-04-30"|"X"|"0000628"|"15000231"|"1999-12-05"|"ST"|"2455525445552000"|"1111-11-11"|75.00|"XXE11111"|"224425"
"2013-04-30"|"Y"|"0000928"|"95000232"|"1999-12-05"|"VT"|"2455525445552000"|"1111-11-11"|95.00|"VVE11111"|"224425"

output file

"2013-04-30"|"X"|"0000628"|"15000231"|"1999-12-05"|"ST"|"24555XXXXXXXXXX"|"1111-11-11"|75.00|"XXE11111"|"224425"
"2013-04-30"|"Y"|"0000928"|"95000232"|"1999-12-05"|"VT"|"24555XXXXXXXXXX"|"1111-11-11"|95.00|"VVE11111"|"224425"

Script I used to run but it is not editing the input file

FILES=/home/auto/*.txt
for f in $FILES
do
echo "Processing $f file..."
cat $f | awk 'BEGIN {FS="|"; OFS="|"} {$7=substr($7, 1, 6)"XXXXXXXXXX\"";print}'
done

but I can't edit the exiting file in the directory. I need to use the sed -i option but it's not working.


I tried using the script in below server but I am getting the following error.

SunOS 5.10      Generic January 2005
echo "hello"

FILES=/export/home/*.txt
for f in $FILES
do
echo "Processing $f file..."
sed -i -r 's/"([^"]{6})[^"]*"/"\1XXXXXXXXXX"/6' "$f"
done

I get

sed: illegal option -- i
Kevin
  • 53,822
  • 15
  • 101
  • 132
Sen
  • 7
  • 2
  • With Solaris `sed`, you will have to redirect the output to a temporary file and then copy or move the temporary file over the original. You may or may not find that it supports the `-r` option; IIRC, it does not. In that case, you will need to use `\(...\)` for grouping and `\{n,m\}` for counting groups. – Jonathan Leffler Feb 14 '14 at 16:20

3 Answers3

2

Using GNU sed with -i optoin

sed -i -r 's/"([^"]{5})[^"]*"/"\1XXXXXXXXXX"/5' file


"2013-04-30"|"X"|"0000628"|"15000231"|"1999-12-05"|"ST"|"24555XXXXXXXXXX"|"1111-11-11"|75.00|"XXE11111"|"224425"
"2013-04-30"|"Y"|"0000928"|"95000232"|"1999-12-05"|"VT"|"24555XXXXXXXXXX"|"1111-11-11"|95.00|"VVE11111"|"224425"
BMW
  • 42,880
  • 12
  • 99
  • 116
  • 2
    Nicely done; you're missing two `X` chars, though. OSX users: use `sed -i '' -E` instead of `sed -i -r`. – mklement0 Feb 14 '14 at 02:54
  • Nice finding,Thanks, I updated. But I have no OSX system to check with your suggestion in OSX sed. :-( – BMW Feb 14 '14 at 02:54
  • Thanks; no worries re OSX - it's not clear what platform the OP uses; I sometimes add the OSX info so that OSX users can benefit from the answers too - often it's just a minor thing, such as different option names. – mklement0 Feb 14 '14 at 02:59
  • If i need to change the sed option to change first 6 digit instead of 5 digit what is the sed command .Pls let me know – Sen Feb 14 '14 at 04:55
  • change from `{5}` to `{6}`, and adjust the number of `X`, – BMW Feb 14 '14 at 04:57
1

if your awk is gnu awk 4.1.0, there is in-place option, read man/info page. otherwise, you could do:

awk '..code..' inputfile > tmpfile && mv tmpfile inputfile

note, the cat is not necessary, could (should) be removed.

mklement0
  • 382,024
  • 64
  • 607
  • 775
Kent
  • 189,393
  • 32
  • 233
  • 301
  • 1
    The `gawk 4.1+` pointer is helpful, but (a) its name is `inplace` and (b) it's an *extension*, not an option; neither `man` nor `info` contain information about it; a demonstration can be found at http://stackoverflow.com/a/16529730/45375 and more info in the online manual at http://www.gnu.org/software/gawk/manual/gawk.html#Extension-Sample-Inplace. – mklement0 Feb 14 '14 at 00:00
  • @mklement0 yes, it is `inplace` and there is explanation and examples in my gawk info page. info gawk, and search `inplace`, you will find – Kent Feb 14 '14 at 09:42
  • Interesting; looks like some distros (e.g., Ubuntu) simply show you the contents of the `man` page when you do `info gawk` - where the `inplace` info is _not_ present. – mklement0 Feb 14 '14 at 22:15
1

A little ugly but you can try something like this with sed

sed -i 's/\(\([^|]*|\)\{6\}\)\(.\{6\}\).\{11\}\(.*\)/\1\3XXXXXXXXXXX\4/' file

So with your existing script, it will be -

FILES=/home/auto/*.txt
for f in $FILES
do
    echo "Processing $f file..."
    sed -i 's/\(\([^|]*|\)\{6\}\)\(.\{6\}\).\{11\}\(.*\)/\1\3XXXXXXXXXXX\4/' "$f"
done
jaypal singh
  • 74,723
  • 23
  • 102
  • 147
  • Jay-Nice i can see the result but can you explain so if i need to modify first 7 digit instead of 5 digit i can do it later .what is 6 , 6 ,11,1,3XXX etc – Sen Feb 14 '14 at 04:15
  • The numbers represent the exact match you want to preserve. I am guessing you mean to say preserve first 7 digits instead of 5 then change the second `\{6\}` to `\{8\}` and reduce 3 X in replacement. – jaypal singh Feb 14 '14 at 04:21