I use SPF/SE from Command Technology. In addition to column-based editing you can exclude and find lines, then replace only within the found or excluded lines. For example, in your case I would do the following:
- Exclude all lines
- Find all occurrences of
<td class="DATA"> in columns 5-22
- Visually verify I have the right selection
- Replace non-blank chars in 17-20 with spaces on non-excluded lines only
- Use copy/overlay to replace the blank spaces
The ability to operate only on non-excluded lines allows you to execute the change on files where the lines in question are not necessarily contiguous.
SPF/SE also has extensive scripting so once you get the sequence of commands correct, you can execute it reliably across many files.
I am not affiliated with the company. But I cut my teeth on mainframe programming using the ISPF editor, which SPF/SE is a clone of, and this is the only thing I've found in the Windows world that has the same level of native column editing. I am a Notepad++ user as well but I fall back to SPF/SE at least a couple of times a day for either column-based editing or find/replace across selected lines.
UPDATE:
I sent the SPF/SE folks a link to this question and invited them to post a better script answer. However, they were a bit cautious about vendors tooting their own horn on a site like this and instead sent me back a macro. The SPF/SE macro language is interpreted C so this may look familiar if you have coded in C. Below is their response:
Assuming the data pattern repeats exactly as described in the
question, the attached macro performs the "fixup" for the entire file
in a single execution. I also attached the data file that I used for
testing.
If the data pattern varies by column, the macro could be
modified to handle other variations not specified in the question.
Vendor's test file:
...random data ...
...random data ...
...random data ...
<tr>
<td class="data"><sup>58</sup>Co</td>
<td class="data">0.</td>
<td class="data">70.8 d</td>
<td class="data">2<sup>+</sup></td>
<td class="data">+4.044(8)</td>
<td class="data"></td>
<td class="data">[<sup>59</sup>Co]</td>
<td class="data">NMR/ON</td>
<td class="data">1972Ni01</td>
</tr>
...random data ...
...random data ...
...random data ...
... should not find this paragraph, not starting in col 2
<tr>
<td class="data"><sup>58</sup>Co</td>
<td class="data">0.</td>
<td class="data">70.8 d</td>
<td class="data">2<sup>+</sup></td>
<td class="data">+4.044(8)</td>
<td class="data"></td>
<td class="data">[<sup>59</sup>Co]</td>
<td class="data">NMR/ON</td>
<td class="data">1972Ni01</td>
</tr>
...random data ...
...random data ...
...random data ...
... should not find this paragraph, too many "data" lines
<tr>
<td class="data"><sup>58</sup>Co</td>
<td class="data">0.</td>
<td class="data">70.8 d</td>
<td class="data">2<sup>+</sup></td>
<td class="data">+4.044(8)</td>
<td class="data"></td>
<td class="data">[<sup>59</sup>Co]</td>
<td class="data">NMR/ON</td>
<td class="data">1972Ni01</td>
<td class="data">1972Ni01</td>
<td class="data">1972Ni01</td>
</tr>
...random data ...
...random data ...
...random data ...
<tr>
<td class="data"><sup>58</sup>Co</td>
<td class="data">0.</td>
<td class="data">70.8 d</td>
<td class="data">2<sup>+</sup></td>
<td class="data">+4.044(8)</td>
<td class="data"></td>
<td class="data">[<sup>59</sup>Co]</td>
<td class="data">NMR/ON</td>
<td class="data">1972Ni01</td>
</tr>
...random data ...
...random data ...
...random data ...
<tr>
<td class="data"><sup>58</sup>Co</td>
<td class="data">0.</td>
<td class="data">70.8 d</td>
<td class="data">2<sup>+</sup></td>
<td class="data">+4.044(8)</td>
<td class="data"></td>
<td class="data">[<sup>59</sup>Co]</td>
<td class="data">NMR/ON</td>
<td class="data">1972Ni01</td>
</tr>
...random data ...
...random data ...
...random data ...
<tr>
<td class="data"><sup>58</sup>Co</td>
<td class="data">0.</td>
<td class="data">70.8 d</td>
<td class="data">2<sup>+</sup></td>
<td class="data">+4.044(8)</td>
<td class="data"></td>
<td class="data">[<sup>59</sup>Co]</td>
<td class="data">NMR/ON</td>
<td class="data">1972Ni01</td>
</tr>
...random data ...
...random data ...
...random data ...
The actual macro:
void FixMarkup(void) {
char *replace[];
char *pcmd;
char *find_str;
int find_count;
int i;
bool done = FALSE;
replace[0] = "isot";
replace[1] = "ener";
replace[2] = "life";
replace[3] = "spin";
replace[4] = "gfac";
replace[5] = "quad";
replace[6] = "ref_";
replace[7] = "meth";
replace[8] = "cite";
while (!done) {
SPFservice("cmd","FIND c'<tr>' 2");
find_count = SPFservice("query","find_string_count");
if (find_count == 1) {
// start of paragraph "<tr>" found
SPFservice("cmd",".A"); // label "<tr>" line as ".A"
SPFservice("cmd","FIND c'</tr>' 2");
find_count = SPFservice("query","find_string_count");
if (find_count == 1) {
// end of paragraph "</tr>" found
SPFservice("cmd",".B"); // label "</tr>" line as ".B"
SPFservice("cmd","LOCATE .A"); // reposition to "<tr>" line
find_str = "c'<td class=\"data\"'";
pcmd = strcompose("FIND ALL ",find_str," 4 .A .B");
SPFservice("cmd",pcmd);
find_count = SPFservice("query","find_string_count");
if (find_count == 9) {
//----------------------------------------------------
// Found paragraph with the following characteristics:
//
// Starts with "<tr>" in col 2
// Ends with "</tr>" in col 2
// Has 9 instances of '<td class="data"' in col 4
//
// Replace "data" in each line with appropriate text
// from array "replace".
//---------------------------------------------------
i = 0;
while (i < 9) {
pcmd = strcompose("CHANGE c'data' '",replace[i],"' 15");
SPFservice("cmd",pcmd);
++i;
} // while
}
}
}
else {
// No more '<tr>' paragraphs found, all done
done = TRUE;
}
} // while
} // FixMarkup