使用批处理脚本更改.tab文件中所有日期字段的值

时间:2014-01-10 18:31:33

标签: batch-file batch-processing

我有.tab<制表符分隔文件>它有很多日期字段。

我的要求是在Windows中使用批处理处理此文件,以便日期字段中的所有值都增加1年。并保存输出文件<包含普通字段和修改日期字段>。

日期字段没有正确的顺序,因此需要使用格式在文件中搜索它们。使用了以下格式:

11/11/2011 
4 years ago
34 months ago
547 days ago 

例如:

Id         date1             date2
1        11/11/2011        3 years ago
2        46 months ago     567 days ago

处理输出文件后的上述内容应如下所示

Id        date1              date2
1        11/11/2012        2 years ago
2        34 months ago     202 days ago


 The data above is formatted for the sake of understanding.. the actual tab delimited file looks like:

Id date1 date2 1 11/11/2011 3年前 2 46个月前567天前

更新:不幸的是,上面粘贴时看起来很奇怪(没有任何换行),在这里附加文件的任何选项?

好的..感谢Magoo给出的想法..这里是包含文件的驱动链接

https://drive.google.com/file/d/0B9XC4xcTUoq1OEZsODZFaTl6aDQ/edit?usp=sharing

但是,示例文件的创建方式如下:

Iddate1date2111 / 11/2013年前几年上24个月之前< 567天前>

我试图在互联网上找到它,但没有运气。写在这里,希望有人可以帮助我。

更新:

Magoo的解决方案有效但无法获得准确的O / P

值得注意的是输入是制表符分隔符(由于格式问题我无法在此处正确粘贴),O / P也应该作为制表符分隔符。

以下是我对代码的了解。

Id  date1   date2      
1   11/11/2012   1  11/11/2013   1  11/11/2014
2 days ago  

另外,这是一个示例文件,实际文件包含50个日期和非日期列的混合(列位置是固定的),所以如果我们可以动态(不确定但可能我们可以搜索以上格式)找到日期字段并更改日期值。

2 个答案:

答案 0 :(得分:2)

下面的批处理文件假定文件中数据的位置是固定的,因此它只需要从适当的列中取出数年。如果日期位置可能发生变化,则需要更复杂的解决方案。

@echo off
setlocal EnableDelayedExpansion

set "line="
for /F "delims=" %%a in (input.txt) do (
   if not defined line (
      set "line=%%a"
      echo !line!
   ) else (
      set "line=%%a"
      set /A y1=!line:~15,2!+1, y2=!line:~28,2!+1
      echo !line:~0,15!!y1!!line:~17,11!!y2!
   )
)

答案 1 :(得分:1)

@ECHO OFF
SETLOCAL
:: The character between the = and closing quote in the next line is a TAB
SET "tab=   "
(
 FOR /f "tokens=1-3delims=%tab%" %%a IN (q21051778.txt) DO (
  SET "line="
  SET "column=%%a"&CALL :process
  SET "column=%%b"&CALL :process
  SET "column=%%c"&CALL :process Y
 )
)>newfile.txt

GOTO :EOF

:process
FOR %%A IN (Field1 Field2 Field3) DO SET "%%R="
:: Format 1 : num/num/num - possibly with leading 0s
FOR /f "tokens=1,2*delims=/" %%A IN ("%column%") DO (
 SET field1=%%A
 SET field2=%%B
 SET field3=%%C
)
IF DEFINED field3 CALL :plaindate
SET "endtext= years ago"
CALL :adjust 10 1
SET "endtext= months ago"
CALL :adjust 11 12
SET "endtext= days ago"
CALL :adjust 9 365
IF "%1"=="Y" (ECHO %line%%tab%%column%
 ) ELSE (
 IF DEFINED line (SET "line=%line%%tab%%column%") else (set "line=%column%")
)
GOTO :eof

GOTO :eof

:: If the last %1 characters of column are %endtext% and the remainder is numeric,
:: subtract %2 from the numeric part
:adjust
CALL SET "endpart=%%column:~-%1%%"
IF /i NOT "%endpart%"=="%endtext%" GOTO :EOF 
CALL SET "endpart=%%column:~0,-%1%%"
CALL :isnumeric %endpart%
IF %numeric%==N GOTO :eof
SET /a endpart=%endpart%-%2
CALL SET "column=%endpart%%%column:~-%1%%"
GOTO :eof

:plaindate
CALL :isnumeric %field1%
IF %numeric%==N GOTO :eof
CALL :isnumeric %field2%
IF %numeric%==N GOTO :eof
CALL :isnumeric %field3%
IF %numeric%==N GOTO :eof
SET /a field3+=1
:: Reconstruct with modified contents
SET column=%field1%/%field2%/%field3%
GOTO :eof

:: Check whether %1 is purely numeric.
:: set 'numeric'=Y or N
:isnumeric
:: Include a leading "9" which will be removed IN the final FOR iteration
SET "numeric=9%1"
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /l %%n IN (0,1,9) DO SET numeric=!numeric:%%n=!
endlocal&SET "numeric=%numeric%"
IF DEFINED numeric (SET numeric=N) ELSE (SET numeric=Y)
GOTO :eof

按照你的要求处理。

无法就地更新文件。必须创建一个新文件。我调用了原始文件q21051778.txt和新文件newfile.txt。你需要改变那些适合自己的。

您可以通过执行

替换原始文件
move /y newfile.txt q21051778.txt

但您只能在测试和验证后执行此操作。

如果您需要更多列,只需将3中的tokens=1-3更改为最大#并添加更多SET "column=..."&CALL :process行,通过递增字母来更改所选列。只有最后一个call :process镜头有Y参数(这是触发输出线的原因)


给出新参数的修订版。此版本应该不受列限制的影响,但在很大程度上依赖于所描述的tab字符的存在。

@ECHO OFF
SETLOCAL
:: The character between the = and closing quote in the next line is a TAB
SET "tab=   "
(
 FOR /f "delims=" %%a IN (q21051778.txt) DO (
  SET "line="
  SET "lineread=%%a"
  CALL :process
 )
)>newfile.txt

GOTO :EOF

:process
FOR /f "tokens=1*delims=%tab%" %%b IN ("%lineread%") DO (SET "column=%%b"&SET "lineread=%%c")
FOR %%A IN (Field1 Field2 Field3) DO SET "%%R="
:: Format 1 : num/num/num - possibly with leading 0s
FOR /f "tokens=1,2*delims=/" %%A IN ("%column%") DO (
 SET field1=%%A
 SET field2=%%B
 SET field3=%%C
)
IF DEFINED field3 CALL :plaindate
SET "endtext= years ago"
CALL :adjust 10 1
SET "endtext= months ago"
CALL :adjust 11 12
SET "endtext= days ago"
CALL :adjust 9 365
IF DEFINED line (SET "line=%line%%tab%%column%") else (set "line=%column%")
IF DEFINED lineread GOTO process
ECHO %line%
GOTO :eof

:: If the last %1 characters of column are %endtext% and the remainder is numeric,
:: subtract %2 from the numeric part
:adjust
CALL SET "endpart=%%column:~-%1%%"
IF /i NOT "%endpart%"=="%endtext%" GOTO :EOF 
CALL SET "endpart=%%column:~0,-%1%%"
CALL :isnumeric %endpart%
IF %numeric%==N GOTO :eof
SET /a endpart=%endpart%-%2
CALL SET "column=%endpart%%%column:~-%1%%"
GOTO :eof

:plaindate
CALL :isnumeric %field1%
IF %numeric%==N GOTO :eof
CALL :isnumeric %field2%
IF %numeric%==N GOTO :eof
CALL :isnumeric %field3%
IF %numeric%==N GOTO :eof
SET /a field3+=1
:: Reconstruct with modified contents
SET column=%field1%/%field2%/%field3%
GOTO :eof

:: Check whether %1 is purely numeric.
:: set 'numeric'=Y or N
:isnumeric
:: Include a leading "9" which will be removed IN the final FOR iteration
SET "numeric=9%1"
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /l %%n IN (0,1,9) DO SET numeric=!numeric:%%n=!
endlocal&SET "numeric=%numeric%"
IF DEFINED numeric (SET numeric=N) ELSE (SET numeric=Y)
GOTO :eof