0

I'm currently in the process of migrating the contents of one SVN server to another. Long story short, I tried using dos2unix to convert some line endings, but it ended up messing with a good portion of the revision logs without fixing anything. Now I am unable to create a complete dump file using svnadmin because of malformed file errors. The files are structured like this:

K (# of chars in following line)
svn:author
V (# of chars in following line)
(author)
K ##
svn:date
V ## 
(date)
K ##
svn:log
V (# of chars in following lines)
revision
commit
text
END

The error stems from the number following the last V being incorrect. So far I have been manually changing the number which involves copying the text, counting the characters somewhere, changing the number, saving, and then running svnadmin dump DIR > dumpfile.dmp to find the next one. I generally wouldn't mind, but running the svnadmin dump command takes a little time and I'm going to be running it a lot.

My question is this: is there any way to write a script that will count the number of characters from line 12 to the end of the line before "END" and then replace the number in line 11? I'm relatively new to unix and have investigated awk, sed, etc but haven't found anything sufficient. I realize those are rather unique parameters so anything that would be helpful is a welcome. Is there perhaps a way to list the files where the char count and number do not match? That would speed up my job significantly.

Thanks.

e: spelling

MSeven
  • 85
  • 1
  • 7

2 Answers2

0

The following script should help:

#!/bin/bash

# Print from line 12 to the end of the file
#   sed -n '12,$p' < $1 
#
# Then count the number of chars in those lines with 
#   wc -c 
#
# Later we take the number of chars in $NUM_CHARS and substract 4 from it 
# (the char count in the "END\n" token, assuming if has a line-end char, if not
# change 4 by 3) with
#   xargs -i expr {} - 4
NUM_CHARS=$(sed -n '12,$p' < $1 | wc -c | xargs -i expr {} - 4)

# Modify the line 11 in file 
sed "11 c\ $NUM_CHARS" $1  

Save this code to a file "script.sh", give it execution permissions and run it as:

./script.sh input_file

To save the content of the new generated file to another, just run the above script as:

./script.sh input_file > new_file

Check if is what you want before do any replace in the original file

higuaro
  • 15,730
  • 4
  • 36
  • 43
  • Hey that's great! One question (and again, let me emphasize I'm relatively new to unix) when I did the `./script` command, it didn't recognize the file. I did `./script.sh` and that worked. However, while it prints the correct number (I changed the -4 to -5, too) it does not actually change the file. It definitely has execution permissions. Any idea why that might be? – MSeven Jul 18 '12 at 21:04
  • sorry, it's a typo, indeed, you have to write `./script.sh` (I'll edit the answer). To change the file, you have to first save the script output to a new file `./script.sh input_file > new_file` because if you use the same input file like this: `./script.sh input_file > input_file` you going to get an empty file (an explanation for that can found [here](http://stackoverflow.com/questions/1895981/why-redirecting-to-same-file-results-in-a-empty-file-in-unix)). But you can use the `-i` option in new versions of `sed` to do [that](http://goo.gl/yH7EC) – higuaro Jul 19 '12 at 19:05
  • No worries. And I was wondering about the bit with the new file, but it worked fine otherwise so I didn't think it was worth mentioning. That explanation is great though, thanks. I'd upvote your answer but I can't yet; nothing personal. – MSeven Jul 19 '12 at 20:02
  • Thanks, don't worry, glad it helped! – higuaro Jul 19 '12 at 22:15
0

Here is another version:

file='path/to/file'
sed -i'' -e"11 s/\d+/$(expr $(tail -n+12 $file | wc -m) - 3)/" $file

or

sed -i'' -e"11 s/\d+/$(expr $(tail -n+12 /path/file | wc -m) - 3)/" /path/file

You will need to either declare $file first or replace it with the path to the file Run those two lines and it should work.

Kassym Dorsel
  • 4,773
  • 1
  • 25
  • 52