views:

38

answers:

3

The corrupt table entry is logged in the error file something like this...

/usr/local/mysql/bin/mysqld: Incorrect key file for table './accounts/headers.MYI'; try to repair it

I want to write a query that will repair this table.

REPAIR TABLE accounts.headers;

What I need to do is search for the first instance of "./" and select the first word i.e. "accounts" and choose the next word "headers". Now use these two variables to write a statement like shown above. Should I write a Shell script for this purpose?

+2  A: 

You can use grep and sed to do this:

pax> cat qq.in
/blah: Incorrect key file for table './accounts/headers.MYI'; try blah
/blah: Incorrect key file for table './pax/diablo.myi'; try blah

pax> grep 'Incorrect key file for ' qq.in | sed
     -e 's/.*\.\//REPAIR TABLE /g'
     -e 's/\//./'
     -e 's/\.[Mm][Yy][Ii].*/;/g'
REPAIR TABLE accounts.headers;
REPAIR TABLE pax.diablo;

Note that I've put all those -e sections on different lines for readability. They should be all on one line to test.

If your version of sed supports case-insensitive searches (like the GNU one does), you can replace that last substitution with 's/\.myi.*/;/Ig'.


To catch lines with different foramts is a bit trickier and will require all the formats to be known to avoid false positives. The following command will catch the alternate format as supplied in your comment:

pax> cat qq.in
/blah: Incorrect key file for table './accounts/headers.MYI'; try blah
/blah: Incorrect key file for table './linus/torvalds.myi'; try blah
/usr/local/mysql/bin/mysqld: Table './beta/search_data' is marked as crashed

allachan@IBM-L3F3936 ~
$ egrep 'Incorrect key|as crashed' qq.in | sed
    -e "s/.*\.\//REPAIR TABLE /g"
    -e "s/[\\.'].*/;/g"
    -e "s/\//./"
REPAIR TABLE accounts.headers;
REPAIR TABLE linus.torvalds;
REPAIR TABLE beta.search_data;
paxdiablo
/usr/local/mysql/bin/mysqld: Table './beta/search_data' is marked as crashed and should be repairedThe error like this does not generate the required statement. What I need to do is to replace the last ' with ; and remove everything after that.
shantanuo
] Got error 126 when reading table './kumar/headers'# Another error that needs to handled.
shantanuo
@shantanuo, you need to _fully_ specify what lines you're looking for. Your original spec had just the form containing `Incorrect key file for table`. Until that's done, no solution can give you what you want without the chance of false positives.
paxdiablo
`sed` can do `grep's` job: `sed -e '/Incorrect key file for /{s/...' -e '...' -e '...}'`
Dennis Williamson
A: 
#!/bin/bash
while read -r line
do
 case "$line" in
   *repair*)
    line="${line##*for table}"
    line="${line%%;*}"
    line=${line#*.\/}
    IFS="/"
    set -- $line
    echo "REPAIR TABLE $1.${2%.MYI*}"
 esac
done <"file"

or just sed

$ sed 's|.*\.\/|REPAIR TABLE |;s|\/|.|;s|\.MYI.*||' file
REPAIR TABLE accounts.headers
ghostdog74
The repair table statement should end with ; The script does not handle other types of errors mentioned above.
shantanuo
A: 

The following is doing what I expect it to do. But I am not too happy with it and will like to know better solution.

awk -F"'./" '{print $2}' | replace "'" ';' | replace "/" "." | replace '.MYI' '' | sed 's/^/; REPAIR TABLE /'

It will output the statements like this...

; REPAIR TABLE kumar.headers;; try to repair it
; REPAIR TABLE raju.headers;; try to repair it

The text after ; will throw an error when mysql executes it, but I can ignore it.

shantanuo