下面给大家讲一讲shell编程在数据处理和模式运行中的妙用。主要有三个方面的内容:
1. Shell的简介
2. bash的基本语法,包括变量、数值运算、判断和循环
3. 两个实例介绍
1.shell简介
Shell是用户和Linux(或者更准确的说,是用户和Linux内核)之间的接口程序。我们在提示符下输入的每个命令都由Shell先解释然后传给Linux内核。所以,可能每个使用Linux服务器或者大型机的人对Shell编程都不陌生。
Bash是大多数UNIX操作系统默认的Shell,系统提示符为“$”,简称为B-Shell,所以我们下面的内容和个例主要是基于Bash的介绍。
作为一门编程语言,它与常用的Ncl和Python一样,都可以进行交互式操作和脚本的批量操作。
交互式 | 脚本 | |
---|---|---|
例子 | Cd ../..Ls -lhMkdir program | 把命令都写入aaa.sh,然后执行bash aaa.sh |
优缺点 | 方便并且可以随时看见结果;但是不适合处理复杂问题 | 适合进行复制的处理;但是脚本编写的成本较高 |
2.Bash基本语法
2.1
变量
定义变量的时候等号两端不允许有空格,如:
var=30
如果有空格,需要用引号将变量值括起来。如果需要使用该变量,需要加上,表示使用它的值,如var,否则会输出变量名。输出的命令是:
echo $var
结果返回30。
我们经常会看见输出变量的时候会带有引号,如双引号、单引号,这与正常的变量有何差异呢?
除此之外,还有种倒单引号,它的内容只能是命令。
2.2
数值运算
例1:用上诉的方法创建3*(5+2)
例2:用上诉方法实现“数值+2”
2.3
条件判断
基本格式:if 条件1 then 命令1 else 命令3 if | 扩充版的格式:if 条件1 then 命令1 elif 条件2 then 命令2fi else 命令3 fi |
---|
判断的内容:
例3:判断文件是否存在,若存在,则输入“ok”;若不存在,则输入“file not exist”。
if [ -f aaa.txt ];then
echo "ok"
else
echo "file not exist"
fi
例4:输入当前文件夹的一级子目录中文件名字
# 将ls的结果保存到变量CUR_DIR中
CUR_DIR=`ls`
# 显示ls的结果
echo $CUR_DIR
for val in $CUR_DIR
do
# 若val是文件,则输出该文件名
if [ -f $val ];then
echo "FILE: $val"
fi
done
2.4
循环
For循环基本格式:for variable in list do commands done | While语句基本语句格式为:while test-condition do commands done |
---|
2.5
数组
Bash中数组是通过空格符号隔开,并且是包含在()里面。引用时从序号0开始。如:Array=(23.5 27 29 31 25.7)
其中array[0]=23.5,array[4]=25.7
例5:数组的相应操作
3.个例展示
前面展示的可能是我们平时编写脚本经常碰到的问题,但是我们设计到数据处理时,往往交互式命令不能满足需求,我们得通过脚本批量执行来达到我们的要求。
a.首先,我们可以通过touch data_processing.sh来创建一个bash脚本;
b.然后,我们可以通过vi编辑,或者sublime/VS studio等进行编辑;
c.最后,通过bash data_processing.sh运行这个脚本即可。
注:值得提醒,如果是在windows下进行编辑的,如sublime下进行的编辑,在运行之前,一定要通过 dos2unix data_processing.sh 来进行格式转换。不然容易报错,一定切记切记!
例6:下载CMIP5的降尺度的数据,包括historical、RCP45和RCP85,20个左右的模式的逐日数据,变量包括pr,tasmin和tasmax。由于一年的数据将近700M,因此需要在下载的过程中就进行预处理,不然会需要9T的空间存储。数据下载链接为:http://nasanex.s3.amazonaws.com/NEX-GDDP/BCSD/historical/day/atmos/pr/r1i1p1/v1.0/pr_day_BCSD_historical_r1i1p1_ACCESS1-0_1950.nc
(这里使用shell+cdo进行下载和预处理。)
例7:问题描述:我们运行模式时,如运行CESM模式,我们一般会经历几个操作步骤,如进行环境的配置;新建个例;进行setup和build;提交作业等。如果我们是在服务器里面通过交互式的命令进行操作,就比较浪费时间,如CESM的build可能耗时较多,得需要十分钟才能结束。因此,我们可以将这些命令都放在一个脚本里面。如下所示:
#! /bin/csh -f
#---------------------------------------------
## case
#---------------------------------------------
setenv CASE FHIST_TEST
#---------------------------------------------
## define directories
#---------------------------------------------
setenv MACH yangxk
setenv HOMEROOT /public/home/diqiuxitong07/yangxianke/CESM_home/CESM2.1.1
setenv RUNROOT $HOMEROOT/output/$CASE/
setenv SCRIPTSROOT $HOMEROOT/cime/scripts
setenv CASEROOT $SCRIPTSROOT/$CASE
setenv OUTPUTDIR $HOMEROOT1/output/$CASE/run
#------------------
## STEP1 create new case 1.9x2.5_tx1v1
#------------------
rm -rf $CASEROOT
rm -rf $RUNROOT
cd $SCRIPTSROOT
./create_newcase --case $CASE --res f09_f09_mg17 --compset FHIST --compiler intel --mach $MACH
echo '----------------------------------------------------------------------'
echo ' create case successfully '
echo '----------------------------------------------------------------------'
#------------------
## STEP2 change pes
#------------------
cd $CASEROOT
./xmlchange --file env_mach_pes.xml --id NTASKS_ATM --val '-4'
./xmlchange --file env_mach_pes.xml --id NTASKS_PER_INST_ATM --val '96'
./xmlchange --file env_mach_pes.xml --id NTASKS_LND --val '-4'
./xmlchange --file env_mach_pes.xml --id NTASKS_PER_INST_LND --val '96'
./xmlchange --file env_mach_pes.xml --id NTASKS_OCN --val '-4'
./xmlchange --file env_mach_pes.xml --id NTASKS_PER_INST_OCN --val '96'
./xmlchange --file env_mach_pes.xml --id NTASKS_WAV --val '-4'
./xmlchange --file env_mach_pes.xml --id NTASKS_PER_INST_WAV --val '96'
./xmlchange --file env_mach_pes.xml --id NTASKS_GLC --val '-4'
./xmlchange --file env_mach_pes.xml --id NTASKS_PER_INST_GLC --val '96'
./xmlchange --file env_mach_pes.xml --id NTASKS_ICE --val '-4'
./xmlchange --file env_mach_pes.xml --id NTASKS_PER_INST_ICE --val '96'
./xmlchange --file env_mach_pes.xml --id NTASKS_ROF --val '-4'
./xmlchange --file env_mach_pes.xml --id NTASKS_PER_INST_ROF --val '96'
# ## changing runtime options
# ./xmlchange --file env_run.xml --id RUN_STARTDATE --val '1979-01-01'
# ./xmlchange --file env_run.xml --id RUN_REFDATE --val '1979-01-01'
# ./xmlchange --file env_run.xml --id STOP_N --val '10'
# ./xmlchange --file env_run.xml --id STOP_OPTION --val 'ndays'
#------------------
## STEP3 setup
#------------------
./case.setup --clean
./case.setup
./preview_run
echo '----------------------------------------------------------------------'
echo ' setup successfully '
echo '----------------------------------------------------------------------'
#------------------
## building
#------------------
./case.build
./case.build --clean
./case.build
# echo '----------------------------------------------------------------------'
# echo ' build successfully '
# echo '----------------------------------------------------------------------'
#------------------
## STEP4 revise parameter
#------------------
cd $RUNROOT/run
mkdir timing
mkdir ./timing/checkpoints
cp ../bld/cesm.exe .
cp /5600/cesm_tutorial/scripts/cesm2.1.1/FHIST_f19/cesm2.job .
cp /public/home/diqiuxitong07/yangxianke/CESM_home/five_vars_replace.nc .
cp /public/home/diqiuxitong07/yangxianke/CESM_home/CESM2.1.1/output/FHIST_f09_1023/run/test.ncl ./cam_vars_replace.ncl
sed -i '/&cam_initfiles_nl/i\&cam_history_nl \n nhtfrq=0,-6 \n mfilt=1,4 \n empty_htapes=.false. \n fincl2="U:I","Q:A","T:M","TS:A","TS:I" \n/' atm_in
sed -i 's/f.e20.FHIST.f09_f09.cesm2_1.001_v2.cam.i.1979-01-01-00000.nc/cam_vars_replace.nc/' atm_in
sed -i 's/nodes=1/nodes=4/' cesm2.job
sed -i '11c mpirun -np 96 ./cesm.exe' cesm2.job
sed -i 's/stop_n = 5/stop_n = 4/' drv_in
sed -i 's/restart_n = 5/restart_n = 2/' drv_in
sed -i 's/FHIST_f09_1023/FHIST_TEST/' cam_vars_replace.ncl
sed -i 's/var_replace.nc/cam_vars_replace.nc/' cam_vars_replace.ncl
ncl cam_vars_replace.ncl
qsub ./cesm2.job
cat cesm2.job
上诉程序的主要步骤:
参考资料:
1.https://www.cnblogs.com/skywang12345/archive/2013/05/30/3106570.html
2.汪君老师shell课件上的部分内容
在此表示感谢。