Перемещение файла / таблицы путем усреднения столбца

У меня есть следующая программа, которая позволяет мне перемещать файл (фактически таблицу), если значение первой строки четвертого столбца является самым высоким (по сравнению с 8 другими файлами, имеющими одинаковый стиль именования). Вот сценарий:

#! /bin/bash river=mississippi highest=1 for model in H08 MPI-HM WBM PCR-GLOBWB do for gcm in GFDL-ESM2M HadGEM2-ES IPSL-CM5A-LR MIROC-ESM-CHEM NorESM1-M do for scenario in hist rcp8p5 rcp4p5 do RESULT=$(awk 'FNR==1 {print $4, FILENAME}' ${model}_${gcm}_${scenario}_${river}[1-9]/${model}_${gcm}_${scenario}_${river}[1-9].txt | sort -n -r| head -1) highest="$(echo $RESULT | cut -d ' ' -f1 )" hifile="$(echo $RESULT | cut -d ' ' -f2 )" echo "highest was $highest in $hifile" cp "$hifile" "/home/stevens/SUMARIO/Fred/highest_discharge/${river}/${model}_${gcm}_${scenario}_${river}.txt" done done done 

Затем я хотел бы адаптировать этот сценарий таким образом, чтобы вместо копирования файла с наивысшим значением (в первой строке, четвертом столбце) я хотел бы скопировать файл, имеющий наивысшее среднее значение в четвертом столбце, в сравнение с другими файлами. Любые советы и советы приветствуются!

  • Копирование рекурсивно файлов с пробелами
  • exec cp не работает из сценария, но работает при выпуске напрямую
  • rsync очень медленный (фактор 8-10) по сравнению с cp при копировании файлов из nfs-share в локальный каталог
  • Когда вы не хотите, чтобы `cp` был рекурсивным?
  • cp: не может статировать ошибку - когда имя файла имеет азиатские символы
  • копировать файлы из родительского местоположения, когда я внутри символьно связанной папки
  • CP: максимальные аргументы числа файлов файлов для утилиты копирования
  • более быстрая альтернатива cp -a
  • 2 Solutions collect form web for “Перемещение файла / таблицы путем усреднения столбца”

    Просто измените способ вычисления РЕЗУЛЬТАТ:

     RESULT=$(awk '{x+=$4} END{print x/NR, FILENAME}' ${model}_${gcm}_${scenario}_${river}[1-9]/${model}_${gcm}_${scenario}_${river}[1-9].txt | sort -n -r| head -1) 

    Что это выше: он суммирует все значения из четвертой строки и печатает в конце результат, деленный на количество строк.

    Поскольку он делит на количество строк, вы получите неожиданные результаты, если у вас есть пустые строки в ваших файлах: сумма не учтет их, но разница будет по количеству строк.

    Редактировать:

    У меня была ошибка в моей первой попытке, которая заставила скрипт учитывать только макс только в последнем файле (поскольку END выполняется после обработки всех файлов)

    Правильная версия:

     awk 'FNR==1 && NR>1 {print x/nr, file;x=0}{x+=$4; nr=FNR; file=FILENAME} END{print x/nr, file, x, nr}' ${model}_${gcm}_${scenario}_${river}[1-9]/${model}_${gcm}_${scenario}_${river}[1-9].txt | sort -n -r| head -1 

    Объяснение:

    • мы печатаем каждый раз, когда предыдущий файл разбирается. Поскольку FNR сбрасывается каждый раз при чтении нового файла, мы проверяем, начал ли мы новый файл (FNR == 1), и мы не находимся в первом файле (NR> 1). Если это так, мы печатаем среднее и имя файла, сохраненные из предыдущего файла. Мы также перезагружаем x (где мы сохраняем среднее значение)
    • в противном случае мы начнем вычислять x. Мы также сохраняем количество записей в этом файле (FNR) и имя файла
    • в конце мы печатаем среднее значение для последнего файла

    Похоже, вы уже поняли, как настроить таргетинг на колонки. Теперь все, что вам нужно сделать, это получить в среднем четвертый столбец из всех 4 файлов и скопировать тот, у которого самый высокий средний (просто повторите то, что вы уже сказали).

    В основном то, что вам нужно сделать, это общий вывод столбца 4 каждого из 4-х файлов и деление на количество строк столбца 4 для получения среднего значения. Затем скопируйте файл с самым высоким средним значением.

    Я ожидаю, что вы просто хотите узнать, как получить средний, правильный?

    Легко получить количество строк, выполняя что-то вроде echo "$file1_col4" | wc -l echo "$file1_col4" | wc -l или wc -l <<< "$file1_col4" , который вы уже должны иметь. Храните каждый в переменной, чтобы разделить ее позже. Поэтому мы просто скажем так:

     file1_col4_rows=$(echo "$file1_col4" | wc -l) 

    Чтобы получить общее количество столбцов, вы должны сделать следующее:

     file1_col4_total=$(echo "$file1_col4" | awk '{total = total + $1}END{print total}') 

    Вы сделали бы это для всех 4 файлов и разделили бы на общее количество строк в столбце, который вы установили в качестве переменной ранее. У Bash есть встроенный интерфейс, но я предпочитаю использовать perl :

     file1_avg=$(perl -e "print $file1_col4_total/$file1_col4_rows") 

    Делая это для всех 4 файлов, вы можете легко увидеть, какой файл имел самый высокий средний 4-й столбец, ссылаясь на переменные $fileN_avg , а затем скопируйте файл с переменной с наибольшим значением:

     file_to_copy="$(echo "file1 $file1_avg file2 $file2_avg file3 $file3_avg file4 $file4_avg" | sort -nrk2 | head -1 | awk '{print $1}')" 

    Тогда просто cp "$file_to_copy" /path/where/it/belongs/

    Linux и Unix - лучшая ОС в мире.