重命名 pcraster mapstack

renaming pcraster mapstack

我有一个文件夹,里面装满了几天内 20 年的降水 pcraster mapstack,我设法从原始 netcdf 文件中提取了我感兴趣的区域的降水值,并将其重命名为这个以避免混淆

precip.19810101 
precip.19810102 
precip.19810103 
precip.19810104 
precip.19810105
...
precip.20111231

但在那之后,我想根据这个日期序列将我的所有文件重命名为 pcraster mapstack

precip00.001
precip00.002
precip00.003
precip00.004
...

我是 python 的初学者,是否有任何帮助或示例可以帮助我弄清楚如何做到这一点? 谢谢

因为你给出了 [batch-file] 标签,我假设,批次是可以的:

@echo off
setlocal enabledelayedexpansion
set /a counti=0
for /f "delims=" %%a in ('dir /b /on precip.*') do (
  set /a counti+=1
  set "counts=000000000!counti!"
  ECHO ren "%%a" "precip!counts:~-6,3!.!counts:~-3!"
)

成功检查输出后删除ECHO

EDITED 以符合您的 precip00.999 is precip01.000 ... until precip07.300 要求(在您的问题中是 precip000.001 在您的评论中是 precip00.001 - 我决定使用第一种格式,可以很容易地更改为第二种格式的 ECHO ren "%%a" "precip!counts:~-5,2!.!counts:~-3!"。)。虽然现在已经不是Batch了,但我还是留下答案吧,也许你至少可以用逻辑

如果您对 Batch 不满意,%variable:~-6,3% 语法解释为 set /?

这是我根据我曾经写过的一些旧 Python 脚本整理的内容:

#! /usr/bin/env python
# Rename PCRaster map stack with names following prefix.yyymmmdd to stack with valid
# PCRaster time step numbers
# Johan van der Knijff
#
# Example input stack:
#
# precip.19810101
# precip.19810102
# precip.19810103
# precip.19810104
# precip.19810105
#
# Then run script with following arguments:
#
# python renpcrstack.py precip 1
#
# Result:
#
# precip00.001
# precip00.002
# precip00.003
# precip00.004
# precip00.005
#

import sys
import os
import argparse
import math
import datetime
import glob

# Create argument parser
parser = argparse.ArgumentParser(
    description="Rename map stack")

def parseCommandLine():
    # Add arguments
    parser.add_argument('prefix',
                        action="store",
                        type=str,
                        help="prefix of input map stack (also used as output prefix)")
    parser.add_argument('stepStartOut',
                        action="store",
                        type=int,
                        help="time step number that is assigned to first map in output stack")

    # Parse arguments
    args = parser.parse_args()

    return(args)

def dateToJulianDay(date):

    # Calculate Julian Day from date
    # Source: https://en.wikipedia.org/wiki/Julian_day#Converting_Julian_or_Gregorian_calendar_date_to_Julian_day_number

    a = (14 - date.month)/12
    y = date.year + 4800 - a
    m = date.month +12*a - 3

    JulianDay = date.day + math.floor((153*m + 2)/5) + 365*y + math.floor(y/4) \
        - math.floor(y/100) + math.floor(y/400) - 32045

    return(JulianDay)

def genStackNames(prefix,start,end, stepSize):
    # Generate list with names of all maps
    # map name is made up of 11 characters, and chars 8 and 9 are
    # separated by a dot. Name starts with prefix, ends with time step
    # number and all character positions in between are filled with zeroes

    # define list that will contain map names
    listMaps = []

    # Count no chars prefix
    charsPrefix = len(prefix)

    # Maximum no chars needed for suffix (end step)
    maxCharsSuffix = len(str(end))

    # No of free positions between pre- and suffix
    noFreePositions = 11 - charsPrefix - maxCharsSuffix

    # Trim prefix if not enough character positions are available 
    if noFreePositions < 0:
        # No of chars to cut from prefix if 11-char limit is exceeded
        charsToCut = charsPrefix + maxCharsSuffix - 11
        charsToKeep = charsPrefix - charsToCut

        # Updated prefix
        prefix = prefix[0:charsToKeep]

        # Updated prefix length
        charsPrefix = len(prefix)

    # Generate name for each step

    for i in range(start,end + 1,stepSize):

        # No of chars in suffix for this step
        charsSuffix = len(str(i))

        # No of zeroes to fill
        noZeroes = 11 - charsPrefix - charsSuffix

        # Total no of chars right of prefix
        charsAfterPrefix = noZeroes + charsSuffix

        # Name of map

        thisName = prefix + (str(i)).zfill(charsAfterPrefix)
        thisFile = thisName[0:8]+"." + thisName[8:11]

        listMaps.append(thisFile)

    return listMaps    

def main():
    # Parse command line arguments
    args = parseCommandLine()
    prefix = args.prefix
    stepStartOut = args.stepStartOut

    # Glob pattern for input maps: prefix + dot + 8 char extension
    pattern = prefix + ".????????"

    # Get list of all input maps based on glob pattern
    mapsIn = glob.glob(pattern)

    # Set time format
    tfmt = "%Y%m%d"

    # Set up dictionary that will act as lookup table between Julian Days (key) 
    # and Date string
    jDayDate = {}

    for map in mapsIn:
        baseNameIn = os.path.splitext(map)[0]
        dateIn = os.path.splitext(map)[1].strip(".")

        # Convert to date / time format
        dt = datetime.datetime.strptime(dateIn, tfmt)

        # Convert date to Julian day number
        jDay = int(dateToJulianDay(dt))

        # Store as key-value pair in dictionary
        jDayDate[jDay] = dateIn

    # Number of input maps (equals number of key-value pairs)
    noMaps = len(jDayDate)

    # Create list of names for output files 
    mapNamesOut = genStackNames(prefix, stepStartOut, noMaps + stepStartOut -1, 1)

    # Iterate over Julian Days (ascending order)

    i = 0

    for key in sorted(jDayDate):
        # Name of input file
        fileIn = prefix + "."+ jDayDate[key]

        # Name of output file
        fileOut = mapNamesOut[i]

        # Rename file
        os.rename(fileIn, fileOut)

        print("Renamed " + fileIn + " ---> " + fileOut)

        i += 1

main()

(或者从 my Github Gist 下载代码。)

您可以从命令行运行它,使用地图堆栈的前缀和第一个输出地图的编号作为参数,例如:

python renpcrmaps.py precip 1

请注意脚本会在适当的位置重命名文件,因此请确保复制原始地图堆栈以防出现问题(我只做了一些 非常 有限对此进行测试!)。

此外,该脚本假设有一个 non-sparse 输入地图堆栈,即在每日地图的情况下,输入地图存在 每个 天。如果缺少天数,输出地图的编号将不是您所期望的。

将所有日期内部转换为儒略日在这里可能有点矫枉过正,但是一旦您开始进行更高级的转换,它确实会让事情变得更容易,因为它为您提供了比日期字符串更易于操作的十进制数字。

我不久前遇到过这个问题。请注意,我是 python 和 PCRaster 的新手,所以不要未经检查就以我为例。

import os
import shutil
import fnmatch
import subprocess
from os import listdir
from os.path import isfile, join
from shutil import copyfile

TipeofFile = 'precip.????????' # original file   
Files = []
for iListFile in sorted(os.listdir('.')):
    if fnmatch.fnmatch(iListFile, TipeofFile):
        Files.append(iListFile)

digiafter = 3 #after the point: .001, .002, 0.003
digitTotal = 8 #total: precipi00000.000 (5.3)
for j in xrange(0, len(Files)):
    num = str(j + 1)    
    nameFile = Files[j]
    putZeros = digitTotal - len(num)
    for x in xrange(0,putZeros):
        num = "0" + num
    precip = num[0:digitTotal-digiafter]+ '.' +num[digitTotal-digiafter:digitTotal]
    precip = str(precip)    
    precip = 'precip' + precip 

    copyfile(nameFile, precip)