Two variables from a line
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 scri开发者_JAVA百科pt for this purpose?
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;
#!/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
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.
精彩评论