Можно перечислить содержание архива и затем передать список комнате с помощью xargs
Пример для tarball (тестируют его без rm
сначала):
tar tfz archive.tar.gz | xargs rm -rf
В Вашем коде говорится для печати строки. Это не говорит нигде, что эта строка является на самом деле арифметическим выражением, которое Вы хотите оцененный. Таким образом, Вы не можете обоснованно ожидать, что Ваше выражение будет оценено.
Ваш код является субоптимальным. $(wc -l)
будет считать количество соответствий возвращенным grep
, но существует более простой путь: выполненный grep -c
вместо этого. $(ls | wc -l)
ненадежный способ считать неточечные файлы в текущем каталоге, потому что вывод ls
не надежно; $(set -- *; echo $#)
надежный способ сделать это (предполагающий, что существует по крайней мере один файл соответствия; если то предположение не могло бы содержать, использовать $(set -- *; if [ -e "$1" ]; then echo $#; else echo 0; fi
, но обратите внимание, что это приведет к делению на нуль, ниже которого необходимо рассматривать как состояние ошибки так или иначе). Таким образом, можно написать код этот путь:
matches=$(grep -c "bla bla blah" blah*)
files=$(set -- *; echo $#)
echo "Blah: $matches / $files * 100"
или можно встроить вычисление этих двух промежуточных значений:
echo "Blah: $(grep -c "bla bla blah" blah*) / $(set -- *; echo $#) * 100"
Теперь, для выполнения арифметики можно использовать встроенное арифметическое расширение оболочки, но это ограничено целочисленными операциями, таким образом, /
оператор округлит в меньшую сторону до ближайшего целого числа.
echo "Blah: $(($matches * 100 / $files))"
В ksh93, zsh и yash, но не в других оболочках, Вы получаете арифметику с плавающей точкой, если существует что-то в выражении для принуждения с плавающей точкой, такие как константа с плавающей точкой. Эта функция не присутствует в Оболочке Bourne, ksh88, pdksh, удар, пепел.
echo "Blah: $(($matches * 100.0 / $files))"
bc
утилита выполняет операции на десятичном числе с произвольной точностью.
echo "Blah: $(echo "scale=2; $matches * 100 / $files" | bc)"
Другая стандартная утилита, которая может выполнить вычисление с плавающей точкой (с меньшим количеством доступных математических функций) awk
.
echo "$matches" "$files" | awk '{print "Blah:", $1 * 100 / $2}'
В первую очередь, Вы не указали свою оболочку. Я предположу, что Вы используете bash
, но заявите это в будущем.
Также очень важно, чтобы Вы не анализировали вывод ls
. Существует хорошая документация относительно того, почему не сделать, таким образом, здесь.
Кроме того, из чего Вы пытаетесь получить вывод процента? Вы, кажется, не пытаетесь вычислить процент в конце. На данный момент я просто сделал точное вычисление, которое Вы перечислили.
Вот маленький сценарий, который должен смочь сделать, это без проблем упомянуло:
#!/bin/bash
_die() {
printf '%s\n' "${@:2}"
exit "$1"
}
(( $# )) || _die 1 "Usage: ${0##*/} pattern <dir>"
[[ $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
при помощи $((
.
~/.bashrc
затем (примечание, Вы также захотите получить ~/.bashrc
от ~/.bash_profile
.
– Chris Down
06.11.2011, 16:21
shopt -s nullglob
намного более легкий способ обработать случай когда *
не соответствует. Кроме того, до н.э является стандартным.
– Gilles 'SO- stop being evil'
06.11.2011, 18:15
bc
по умолчанию (Дуга Linux бесцеремонно). Что касается nullglob, я должен был бы все еще сделать проверки независимо.
– Chris Down
06.11.2011, 18:28
Что-то вроде этого?
echo "scale=2;100*`grep 'bla bla bla' bla* | wc -l`/`cat bla* | wc -l`" | bc
bla*
создан или удален, в то время как Вы выполняете эту команду, затем grep
и cat
может работать через различные наборы файлов. Я не знаю где cat bla*
прибывает из, тем не менее, это, кажется, не находится в требованиях.
– Gilles 'SO- stop being evil'
06.11.2011, 18:18
nullglob
опция оболочки не избежать "никаких файлов соответствия возвращает проблему" шаблона шарика.num_files=$(shopt -s nullglob; set -- *; echo $#)
– janmoesen 06.11.2011, 22:22