Как я могу вычислить математическое уравнение, по одному на строку в файле?

Если это поможет.... Для этого я написал небольшой bash-скрипт.... У вас должен быть установлен ffmpeg/ flac.

Как это работает:

Требуется 2 аргумента:

  1. Папка вашей фонотеки (flac/ogg/mp3...)
  2. Папку назначения (нужно создать до ).

Он производит:

  • Точная копия из исходной папки в папку назначения с :
    • в которые скопированы неflac-файлы.
    • файлы flac преобразованы в mp3 (высокое качество VBR)
  • Файл run.shс командами для преобразования файлов flac (этот скрипт выполняется автоматически ).

#!/bin/bash

FLAC_PATH=$1
CONV_PATH=$2

DEBUG=0;

function usage {
  echo "";
  echo "    This script convert all flac files from a folder to mp3 files to a second folder";
  echo "";
  echo "    Usage :";
  echo "       ./conv.sh {Source Folder} {Destination Folder}";
  echo "        note : booth folder must exist before starting this script";
  echo "               files other than flac are copied to the destination folder";
  echo "";
}

if [ ! -d "$2" ]; then
  echo "";
  echo " ERROR : [$2] is not a directory.";
  usage
  exit 1
fi;

if [ ! -d "$2" ]; then
  echo "";
  echo " ERROR : [$2] is not a directory.";
  usage
  exit 1
fi;

COMMANDS="run.sh"
echo "" > run.sh
echo " convert from $FLAC_PATH to $CONV_PATH ";

find "${FLAC_PATH}" -type f |while read myFile; do
  SRC_DIR=${myFile%/*}
  SRC_FILE=${myFile##*/}
  DST_DIR=$CONV_PATH/$SRC_DIR
  mkdir -p "${DST_DIR}"
  # TEST if the file is a flac....
  metaflac --show-md5sum "${myFile}" 2>/dev/null 1>/dev/null
  if [ $? -eq 0 ]; then
    echo -n "  *** $myFile [FLAC !] : "
    DST_FILE=${myFile%.*}
    OUT_PATH="${DST_DIR}/$( echo $SRC_FILE | sed -e 's/.flac$/.mp3/')"

    if [ $DEBUG == 1 ]; then
      echo "  SRC = $myFile";
      echo "  OUT = $OUT_PATH"
    fi;

    if [ -f "$OUT_PATH" ]; then
      echo "  exist, do nothing !";
    else
      echo "  add to compress list !";
      echo "ffmpeg -y -i \"${myFile}\" -codec:a libmp3lame -q:a 0 -map_metadata 0 -id3v2_version 3 \"${OUT_PATH}\" " >> $COMMANDS
    fi;

  else
     echo -n "  *** $SRC_FILE  [NOT FLAC] : "
     if [ -f "${CONV_PATH}/${myFile}" ]; then
       echo " exist, do nothing !"
     else
       echo "  copy."
       cp "${myFile}" "${CONV_PATH}/${myFile}"
     fi
  fi

done;

echo " And now, CONVERT THE FLAC's!!! "
sh run.sh

7
23.11.2019, 20:54
9 ответов

Кажется, это awkпомогает:

while IFS= read i; do 
  awk "BEGIN { print ($i) }"
done < math.txt

Из здесь

Обратите внимание, что мы используем ($i)вместо $i, чтобы избежать проблем с арифметическими выражениями, например1 > 2(print 1 > 2напечатает 1в файл с именем 2, а print (1 > 2)напечатает 0, результат этого арифметического выражения ).

Обратите внимание, что поскольку расширение переменной оболочки $iинтерпретируется awkкак код , это, по сути, уязвимость внедрения кода . Если вы не можете гарантировать, что файл содержит только допустимые арифметические выражения, вам следует установить некоторую проверку ввода. Например, если в файле была строка system("rm -rf ~"), это могло иметь драматические последствия.

13
27.01.2020, 20:13

Если у вас есть Perl:

perl -ne 'print eval $_,"\n"' math.txt

(С помощью этого )я получаю на своем ноутбуке 50000 строк в секунду.

7
27.01.2020, 20:13

Использование awk/python:

python -c "$(awk '{printf "print %s;", $0}' math.txt)"

awkиспользуется здесь для форматирования вашего файла во входные данные, которые примет python, затем python выполняет работу.

В качестве альтернативы perlможно использовать почти таким же образом:

perl -le "$(awk '{printf "print %s;", $0}' math.txt)"
2
27.01.2020, 20:13

Со старым -хорошим Питоном:

$ python -c $'import sys;\nfor line in sys.stdin:print(eval(line))' <math.txt
2275.52
2091.75
2162.88
2174.94
2178.82
2168.37
2268.71
2194.17
2262.52
2271.55
2134.76
2058.9
2029.63
2077.73
2164.49
4
27.01.2020, 20:13

непосредственно в bash/ksh(Редактировать:Как оказалось, bashне может этого сделать, толькоksh-спасибо за указание на это):

$ while read l
> do
> echo $(($l))
> done <<!
> 37 * 60 + 55.52
> 34 * 60 + 51.75
> 36 * 60 + 2.88
> 36 * 60 + 14.94
> 36 * 60 + 18.82
> 36 * 60 + 8.37
> 37 * 60 + 48.71
> 36 * 60 + 34.17
> 37 * 60 + 42.52
> 37 * 60 + 51.55
> 35 * 60 + 34.76
> 34 * 60 + 18.90
> 33 * 60 + 49.63
> 34 * 60 + 37.73
> 36 * 60 + 4.49
> !
2275.52
2091.75
2162.88
2174.94
2178.82
2168.37
2268.71
2194.17
2262.52
2271.55
2134.76
2058.9
2029.63
2077.73
2164.49

Для этого может потребоваться довольно свежая версия вашей оболочки -$((...)), используемая только для целочисленной арифметики.

3
27.01.2020, 20:13

Если вам нужны только результаты, я получил ответ, предоставленный @francois -p

Для развлечения и игр добавьте pasteиsed:

$ paste <(sed 's/\($\)/\1\t=/g' somefile) <(bc < somefile)
37 * 60 + 55.52 =   2275.52
34 * 60 + 51.75 =   2091.75
36 * 60 + 2.88  =   2162.88
36 * 60 + 14.94 =   2174.94
36 * 60 + 18.82 =   2178.82
36 * 60 + 8.37  =   2168.37
37 * 60 + 48.71 =   2268.71
36 * 60 + 34.17 =   2194.17
37 * 60 + 42.52 =   2262.52
37 * 60 + 51.55 =   2271.55
35 * 60 + 34.76 =   2134.76
34 * 60 + 18.90 =   2058.90
33 * 60 + 49.63 =   2029.63
34 * 60 + 37.73 =   2077.73
36 * 60 + 4.49  =   2164.49
3
27.01.2020, 20:13

С Perl:

perl -ple '$_=eval' ex
perl -nE 'say eval' ex

с Python:

python3 -qi < ex
python3 -qic 'import sys; sys.ps1=""' < ex

С Хаскеллом:

ghci < ex
ghci < ex | grep -Po '> \S+$'

С известковым:

calc -f ex      # apt install apcalc if necessary
3
27.01.2020, 20:13

Непосредственно с помощьюawk:

awk '{ printf "%f\n", $0 }' math.txt

$0представляет всю строку, которая считывается строка за строкой из файла.

Кроме того, он не восприимчив к неприятным инъекциям. Он будет оценивать строку только как число с плавающей запятой.

2
27.01.2020, 20:13

Просто передайте беспорядок в bc -l, он вернет один результат строки для каждой строки выражения. (-lзагружает математическую библиотеку, а также устанавливает для scaleболее высокое значение, что дает дробные результаты.)

0
25.02.2020, 15:07

Теги

Похожие вопросы