0

I have a test file called testPage with the following text:

|| '''Title1''' || '''Title2''' || '''Title3''' ||
|| Cell11 || Cell12 || Cell13 ||
|| Cell21 || Cell22 ||
|| Cell31 || Cell32 ||
|| Cell41 || Cell42 ||
|| CEll51 || Cell52 ||
|| Cell61 || Cell62 ||
|| Cell71 || Cell72 ||

That I want to look like:

{|
|'''Title1''' || '''Title2''' || '''Title3''' ||
|-
| Cell11 || Cell12 || Cell13 ||
|-
| Cell21 || Cell22 ||
|-
| Cell31 || Cell32 ||
|-
| Cell41 || Cell42 ||
|-
| CEll51 || Cell52 ||
|-
| Cell61 || Cell62 ||
|-
| Cell71 || Cell72
|}

I have a script:

#!/bin/bash

isTable=0
beginTable="^\|\|"
lineNum=1

while IFS= read -r line
do
    echo "lineNum: $lineNum, line: $line, isTable: $isTable"
    if [[ $line =~ $beginTable ]]
    then
        if [ "$isTable" -eq "0" ]
        then
            isTable=1
            sed -r $lineNum's_\|\|_\{\|\n\|_' -i testPage #Begin table
            echo "begin table"
        else
            sed -r $lineNum's_^\|\|_\|-\n\|_' -i testPage #Define row ##DOESN'T WORK##
            echo "start of row"
        fi
    else
        if [ "$isTable" -eq "1" ]
        then
            isTable=0
            sed -r $lineNum's_(.*)$_\1\n\|\}\n_' -i testPage #End table ##WEIRD RESULT##
            echo "end table"
        fi
    fi
((lineNum++))
done < testPage

That gives the result:

{|
| '''Title1''' || '''Title2''' || '''Title3''' ||
|-
| Cell11 || Cell12 || Cell13 ||
|-
| Cell21 || Cell22 ||
|-
| Cell31 || Cell32 ||
|| Cell41 || Cell42 ||
|}

|| CEll51 || Cell52 ||
|| Cell61 || Cell62 ||
|| Cell71 || Cell72 ||

I can't figure out why it stops substituting after three iterations even though the loop reports the appropriate line and line number as well as matching the appropriate logic.

Any help is appreciated.

For clarity, testPage is a portion of a larger file, so sed beginning and ending flags (i.e., doing different things on lines 1 and $) won't do for me.

  • 2
    This is probably related, but I'm not positive so I'll make it a comment. Modifying a file while you're iterating over it is almost always going to be problematic. You probably need to find a way to separate iterating over the file from modifying it – Eric Renouf Aug 24 '15 at 17:40
  • @EricRenouf Might be a good point. Beaunus, what happens if you replace sed [...] -i testPage with sed [...] testPage >> newfile and check newfile? – Fiximan Aug 24 '15 at 18:28
  • @EricRenouf you may be right I'm investigating other ways to go about doing this but ultimately I want to edit the original file. – Beaunus Aug 24 '15 at 19:10
  • @Fiximan this works but shows each iteration so I get a copy of testPage for each line that exists with the one line edited. Let me know if this doesn't make sense I'll try a bit harder to explain my result. – Beaunus Aug 24 '15 at 19:12
  • I get your point: use your replacements as in sed -n -r $lineNum's_\|\|_\{\|\n\|_p' then, i.e. suppress output (-n) and print the replaced line ( p in sed operation). newfile has the correct output then, you have found the source of your problem: The number of lines should not change while iterating over the lines of a file. – Fiximan Aug 24 '15 at 19:43
0
sed 's/||$/&\n|-/;s/^||/|/;1s/^/{|\n/;$s/-$/}/' file

Note \n is GNU sed only, thus should otherwise be

sed 's/||$/||\
|-/;s/^||/|/;1s/^/{|\
/;$s/-$/}/' file
|improve this answer|||||
  • I appreciate this. It does what I asked, but I didn't ask appropriately. Unfortunately, the testPage file text that I provided is a portion of a larger file thus the beginning and ending flags,'1s' and '$s', won't work for me. – Beaunus Aug 24 '15 at 19:06
  • well, if you know/can determine the integer numbers for start and end lines of your block (e.g. via grep -n and a sed on the output), you can put the expression in double quotes and use e.g. $start and $end in the code. – Fiximan Aug 24 '15 at 19:41
  • And use a range for the other replacements. – Fiximan Aug 24 '15 at 19:46
0

I used a combination answers to achieve my desired result.

#!/bin/bash

isTable=0
beginTable="^\|\|"
lineNum=1
tableCount=0

while IFS= read -r line #Print changes to temp file
do
    if [[ $line =~ $beginTable ]]
    then
        if [ "$isTable" -eq "0" ]
        then
            isTable=1
            ((tableCount++))
            > $1_$tableCount
            sed -n -r $lineNum's_^\|\|_\{\|\n\|_p' $1 >> $1_$tableCount #Begin table
            sed -r $lineNum's_^\|\|_@'$tableCount'@_' -i $1
        else
            sed -n -r $lineNum's_^\|\|_\|-\n\|_p' $1 >> $1_$tableCount #Define row
        fi
    else
        if [ "$isTable" -eq "1" ]
        then
            isTable=0
            sed -n -r $lineNum's_(.*)$_\1\|\}\n_p' $1 >> $1_$tableCount #End table
        fi
    fi
((lineNum++))
done < $1

for ((n=1;n<=$tableCount;n++))
do
    sed -e '/@'$n'@/r '$1'_'$n'' -e '/^@'$n'@/d;/^||/d' -i $1
    rm "$1"_"$n"
done

I print each table to a different numbered file and then sed read each of those into the original file.

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.