Bash-скрипт для команды CDO для работы с разными файлами

Вопрос или проблема

Я новичок в UNIX и хочу применить команду CDO (Climate Data Operator) “remapbil” для преобразования сетки (из проекции в географическую координатную систему). Она отлично работает для одного файла с следующей командой:

cdo remapbil,target.grd hurs_EUR-11_ICHEC-EC-EARTH_rcp26_r3i1p1_DMI-HIRHAM5_v1_day_20360101-20401231.nc hurs_36_40_bil.nc

Но мне нужно сделать это для множества разных файлов. По этой причине я попытался написать следующий скрипт bash, который позволит мне запустить команду remapbil для всех файлов в моем каталоге:

#!/bin/bash

for i in *.nc;
do
echo $i
for file in "ls *.nc"; do
cdo remapbil,target.grd tas_EUR-11_ICHEC-EC-EARTH_rcp45_r3i1p1_DMI-HIRHAM5_v1_day_20210101-20251231.nc > tas_$i_bil.nc
done
done

Но я постоянно получаю следующую ошибку:

cdo remapbil (Abort): Слишком мало потоков указано! Оператор требует 1 входной и 1 выходной поток.

Может кто-то помочь мне, это было бы замечательно

Команда for file in "ls *.nc"; do . . . ; done выполнит команду один раз с литеральным аргументом ls *.nc – как вы можете подтвердить следующим образом:

$ ls *.nc
bar.nc  foo.nc
$ for file in "ls *.nc"; do echo "$file" ; done
ls *.nc

Вероятно, вы намеревались использовать подстановку команд с помощью обратных кавычек вместо двойных кавычек но это было бы плохой идеей1 и не является необходимым, так как вы уже перебираете файлы, используя (безопасный при наличии кавычек) шаблон оболочки. Итак:

for i in *.nc;
do
echo $i
cdo remapbil,target.grd  "$i" > "tas_${i}_bil.nc"
done

Если вы хотите удалить и заменить расширение в выходном файле, вы можете изменить "tas_${i}_bil.nc" на "tas_${i%.nc}_bil.nc"


  1. Почему не парсить ls?

Ответ или решение

Конечно, рад помочь вам с написанием bash-скрипта для выполнения команды CDO "remapbil" на нескольких файлах. Вы правильно заметили, что в вашем первоначальном коде есть несколько ошибок. Давайте исправим это и сделаем его работоспособным.

Вот пример исправленного скрипта:

#!/bin/bash

# Проверьте, существует ли файл target.grd
if [[ ! -f target.grd ]]; then
    echo "Файл target.grd не найден!"
    exit 1
fi

# Перебор всех файлов с расширением .nc в текущем каталоге
for i in *.nc; do
    # Проверка на существование файлов .nc
    if [[ ! -e "$i" ]]; then
        echo "Нет файлов с расширением .nc в каталоге."
        exit 1
    fi

    echo "Обработка файла: $i"

    # Выполнение команды remapbil с созданием выходного файла с измененным именем
    cdo remapbil,target.grd "$i" "tas_${i%.nc}_bil.nc"

    # Проверка на успешность выполнения команды
    if [[ $? -ne 0 ]]; then
        echo "Ошибка при обработке файла: $i"
    else
        echo "Файл успешно обработан и сохранен как: tas_${i%.nc}_bil.nc"
    fi
done

Объяснение кода:

  1. Проверка наличия файла target.grd: Скрипт сначала проверяет, существует ли файл target.grd. Если он отсутствует, скрипт завершится с сообщением об ошибке.

  2. Перебор файлов: Используется цикл for, чтобы перебрать все файлы с расширением .nc в текущем каталоге.

  3. Проверка существования файлов: Перед выполнением операции, скрипт проверяет, существуют ли вообще какие-либо файлы .nc. Если нет – выводится сообщение об этом и выполнение завершается.

  4. Выполнение команды CDO: Для каждого файла выполняется команда cdo remapbil. Выходной файл создается с помощью подстановки tas_${i%.nc}_bil.nc, что позволяет удалять расширение .nc и добавлять tas_ и _bil.nc.

  5. Проверка на ошибки: Скрипт проверяет код возврата предыдущей команды с помощью $?. Если команда не была выполнена успешно, выводится ошибка.

Запуск скрипта:

Перед запуском убедитесь, что у вас есть права на исполнение скрипта. Используйте команду:

chmod +x имя_скрипта.sh

И затем запустите его:

./имя_скрипта.sh

Этот скрипт должен корректно обработать все файлы .nc в указанном вами каталоге и создать соответствующие выходные файлы.

Оцените материал
Добавить комментарий

Капча загружается...