Вопрос или проблема
Я новичок в 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"
Ответ или решение
Конечно, рад помочь вам с написанием 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
Объяснение кода:
-
Проверка наличия файла target.grd: Скрипт сначала проверяет, существует ли файл
target.grd
. Если он отсутствует, скрипт завершится с сообщением об ошибке. -
Перебор файлов: Используется цикл
for
, чтобы перебрать все файлы с расширением.nc
в текущем каталоге. -
Проверка существования файлов: Перед выполнением операции, скрипт проверяет, существуют ли вообще какие-либо файлы
.nc
. Если нет – выводится сообщение об этом и выполнение завершается. -
Выполнение команды CDO: Для каждого файла выполняется команда
cdo remapbil
. Выходной файл создается с помощью подстановкиtas_${i%.nc}_bil.nc
, что позволяет удалять расширение.nc
и добавлятьtas_
и_bil.nc
. -
Проверка на ошибки: Скрипт проверяет код возврата предыдущей команды с помощью
$?
. Если команда не была выполнена успешно, выводится ошибка.
Запуск скрипта:
Перед запуском убедитесь, что у вас есть права на исполнение скрипта. Используйте команду:
chmod +x имя_скрипта.sh
И затем запустите его:
./имя_скрипта.sh
Этот скрипт должен корректно обработать все файлы .nc в указанном вами каталоге и создать соответствующие выходные файлы.