В первую очередь, Вы не указали свою оболочку. Я предположу, что Вы используете bash
, но заявите это в будущем.
Также очень важно, чтобы Вы не анализировали вывод ls
. Существует хорошая документация относительно того, почему не сделать, таким образом, здесь.
Кроме того, из чего Вы пытаетесь получить вывод процента? Вы, кажется, не пытаетесь вычислить процент в конце. На данный момент я просто сделал точное вычисление, которое Вы перечислили.
Вот маленький сценарий, который должен смочь сделать, это без проблем упомянуло:
#!/bin/bash
_die() {
printf '%s\n' "${@:2}"
exit "$1"
}
(( $# )) || _die 1 "Usage: ${0##*/} pattern "
[[ $2 ]] && _dir=$2 || _dir=.
[[ -d ${_dir} ]] || _die 2 "Directory does not exist: ${_dir}"
for _file in "${_dir}"/*; do
[[ -f ${_file} ]] && _files+=( "${_file}" )
done
(( ${#_files[@]} )) || _die 3 'No files matched by glob, not attempting to divide by 0.'
# We pass the same files found to grep instead of reglobbing to avoid a race condition.
while IFS= read -r _number_of_matches; do
(( _total_matches )) && (( _total_matches+=_number_of_matches )) || _total_matches=${_number_of_matches}
done < <(grep -hc "$1" "${_files[@]}")
(( _total_matches )) || _die 4 "Nothing matched by expression: $1"
printf 'Blah: %s\n' "$(bc <<< "${_total_matches}/${#_files[@]}")"
Примите во внимание это bc
не является портативным. Если Вы не возражаете использовать целочисленную арифметику, Вы могли бы использовать оболочку, чтобы вычислить и возвратить ее вместо того, чтобы передать ее bc
при помощи $((
.
mysqldump -uuser -ppass database < show_tables.sql |
xargs -I TableName sh -c 'mysqldump -uuser -ppass database TableName > TableName.sql'
Принятие имен таблиц не может содержать новые строки,
mysqldump -uuser -ppass database < show_tables.sql |
while IFS= read -r table; do
mysqldump -uuser -ppass database "$table" > and_here.sql
done
read
чтения до новой строки, независимо от как IFS
установлен..IFS
только говорит read
как разделить то, что это читает (на основе -d
который является \n
по умолчанию).. read
не нуждается IFS
вообще при чтении просто единственного var ($table
).. Действительно, для просто единственного var, единственное время Вам нужно IFS=
когда Вы хотите обслужить встроенный \n
, в этом случае Вы, должно быть, разграничили пустым указателем вход и IFS= read -d $'\0'
.. Следующее хорошо работает без измененной IFS: printf "a b\nx y\n" |while read -r x; do echo $((i+=1))"$x="; done
– Peter.O
16.04.2012, 12:59
IFS=
предотвращает read
от разделения ведущего и запаздывающего пробела (попытка read -r a <<<' foo '
по сравнению с IFS= read -r a <<<' foo '
). Если имена таблиц не будут иметь таких вещей затем, то это не будет иметь значения, но я добавил его для безопасности в случае, если они делают.
– jw013
16.04.2012, 14:24
"for safety";
хороший идеал... Я действительно обычно использую -r
, и даже set -f
отключить globbing. Я теперь удостоверюсь, что обычно использую IFS=
– Peter.O
16.04.2012, 16:08
В руководстве говорится
Arrays are assigned to using compound assignments of the form name=(value1 ... valuen),
таким образом, Вам просто нужен путь, помещает вывод Вашей команды, где он говорит value1 ... valuen
.
Можно сделать это как это
databases=( $(mysqldump -uuser -ppass database < show_tables.sql) )
и затем выполните итерации по ним как это
for database in ${databases[*]}; do
...
done
но на всякий случай Ваше имя таблицы является действительно странным и содержит некоторые новые строки, я рекомендовал бы использовать mysql -Bse
перечислять базы данных и/или таблицы и использование while read IFS=
как jw013 предлагает (возможно без -r
опция).
mysql database -e 'show tables' | while read table
do mysqldump -uuser -ppass database "$table" -r "$table.sql"
done
Работы с пробелами в таблицах, также.
----------
. Добавьте -B
опция выключить их. Кроме того, как Ваш ответ отличается от jw013?
– Mikel
17.04.2012, 07:28
mysql database -e 'show tables' | while read table
do mysqldump -uuser -ppass database "$table" -r "$table.sql"
done
Работы с пробелами в таблицах, также.