如何在字符串中查找下划线的最后一个实例?

时间:2015-03-30 15:09:07

标签: batch-file find

我正在寻找一种解决方案,以便在尝试导入之前检查目录中是否存在文件。我有脚本:

for %%a in (*.csv) do if exist "D:\Check\%%a" ( 
    del "%%a" 
) else ( 
    move "%%a" "D:\Import" 
)

检查完整文件名时哪个好。但是,在这种情况下,我想检查最后一个下划线字符:

完整的文件名例如是:`940_20150330_12345_000288.csv。文件中的“_”数量会有所不同,大多数会有3个,但有些会有4个,5个,6个或7个。

我想删除在Check目录中找到的匹配940_20150330_12345*.csv的所有文件,如果没有找到文件,则移至导入目录。

我不确定我需要做什么来替换for %%a in (*.csv)才能找到最后一个下划线。

3 个答案:

答案 0 :(得分:0)

如果您的文件始终采用给定的格式(四个组件以下划线分隔),那么您可以尝试以下方式:

for %%a in (*.csv) do for /f "tokens=1,2,3 delims=_" %%b in ("%%a") do if exist "D:\Check\%%b_%%c_%%d_*.csv" (
    del "D:\Check\%%b_%%c_%%d_*.csv"
    del "%%a"
) else (
    move "%%a" "D:\Import"
)

对于每个.csv文件,它运行第二个for命令,该命令提取前三个下划线分隔的组件并测试以查看以这些组件开头的任何文件是否在{{1 }}目录,删除它们和原始目录或将原始目录移动到Check目录。

修改

如果您的Windows版本为Import,那么您可以使用:

sed

用“下划线+字符串不包含下划线+ .csv”之前的位替换每个文件名,这实际上选择了最后一个组件之前的位。

如果你没有这个(它有几个地方可用;我有for %%a in (*.csv) do for /f %%b in ('echo "%%a" ^| sed "s/\(.*\)_[^_]*.csv/\1/"') do if exist "%%b_*.csv" ... 命令行工具的副本),那么到目前为止我能想到的最好的是有几个循环,从最长的组件数开始:

Git

每次减少REM check 7 underscores for %%a in (*_*_*_*_*_*_*_*.csv) do for /f "tokens=1,2,3,4,5,6,7 delims=_" %%b in ("%%a") do if exist "D:\Check\%%b_%%c_%%d_%%e_%%f_%%g_%%h_*.csv" ( del "D:\Check\%%b_%%c_%%d_%%e_%%f_%%g_%%h_*.csv" del "%%a" ) else ( move "%%a" "D:\Import" ) REM check 6 underscores for %%a in (*_*_*_*_*_*_*.csv) do for /f "tokens=1,2,3,4,5,6 delims=_" %%b in ("%%a") do if exist "D:\Check\%%b_%%c_%%d_%%e_%%f_%%g_*.csv" ( del "D:\Check\%%b_%%c_%%d_%%e_%%f_%%g_*.csv" del "%%a" ) else ( move "%%a" "D:\Import" ) REM ...etc... 组件的数量,*_*_*...的数量和tokens位的数量。

答案 1 :(得分:0)

如果文件名具有您的示例形式,则下面的批处理文件可以解决您的问题:

@echo off
setlocal EnableDelayedExpansion

for %%a in (*.csv) do (
   set fileName=%%~Na
   for %%b in (!fileName:_= !) do set lastPart=%%b
   set fileName=%%a
   for %%b in (!lastPart!) do if exist "D:\Check\!filename:_%%b.csv=*.csv!" ( 
       del "%%a" 
   ) else ( 
       move "%%a" "D:\Import" 
   )
)

如果文件名包含空格,逗号或分号,则此方法将失败。它还消除了感叹号。

答案 2 :(得分:0)

我将_转换为\并在前面使用带有#的第二个FOR循环并获得结果假冒"路径",忽略"名称" 。如果没有\#,或者原始名称以_开头,我需要前导_

我剥离了领先的\#

如果结果未定义,则文件没有_,我只是检查全名是否存在。

如果有结果,则将\转换回_,然后执行两次IF EXIST测试。一个用于" EverythingUntilLastUnderscore _ *。csv",另一个用于" EverythingUntilLastUnderscore.csv"

@echo off
setlocal enableDelayedExpansion
set "check=D:\Check\"
set "import=D:\Import"
for %%A in (*.csv) do (
  set "found="
  set "file=%%A"
  for %%B in ("\#!file:_=\!") do set "base=%%~pB"
  set "base=!base:~2!"
  if defined base (
    set "base=!base:\=_!"
    if exist "!check!!base!*%%~xA"      set found=1
    if exist "!check!!base:~0,-1!%%~xA" set found=1
  ) else (
    if exist "!check!%%A" set found=1
  )
  if defined found (
    del "%%A"
  ) else (
    move "%%A" "%import%"
  )
)