DragAndDrop.bat:看起来一个很好的解决方案是使用单个 .vbs 文件 (DragAndDropTrim12Add_clean.vbs) 中的检查和平衡 (what-if) 功能的单个 .bat 文件 (DragAndDrop.bat)。请参阅下面两个文件的语法。一些额外的脚本被用来保持脚本行相当短。这已更新到 1.1 版,它添加了一个功能,让用户可以选择通过键入新的目标目录来指定。默认有新文件(复制或重命名)假定旧文件的路径。如果选中命令窗口属性快速编辑模式复选框,则可以轻松粘贴到新的目标目录中。输入提示中的向上箭头也将带您返回之前的输入。如果您尝试在非 cScript 模式下运行 DragAndDropTrim12Add_clean.vbs,则会生成弹出消息,但除外,所有用户的焦点都可以保留在命令行上。如果您选择修改 DragAndDrop.bat 文件,请小心避免在 set 命令上添加尾随空格。还建议继续使用 setlocal 调用以减少对周围环境的影响。
:DragAndDropDotBat
@Title DragAndDrop.bat
@rem Rev 1.1 11/10/2013 to add optional user specified target directory.
@rem Labels are followed with "rem :LabelName" for easy GoTo troubleshooting.
@rem Script works best if CMD window buffer width set above file lengths.
@echo off
@echo ******* THIS IS FILE %0 %DATE% %TIME: =0% ********
@echo User Choices are not case sensitive.
@echo Leading or trailing white spaces are trimmed in derived names.
@echo If Notepad OldFile is selected, the process will loop and run again.
setlocal
REM YOU MUST MANUALLY EDIT AND SET THE NEXT LINE PATH!!!!!
Set FileToCall="x:\Scripts\DragAndDropTrim12Add_clean.vbs"
Set BatNewFileTargetDir="UseOldFilePath"
Set Per0=%0
Set Per0=%Per0:"=%
Set ProCount=0
prompt :
:RunProcess
rem :RunProcess
Set /A ProCount=%ProCount% + 1
:SameAgain
rem :SameAgain
@echo off
Set BatUserCho=S
Set ProCntZeroFill=000%ProCount%
Set strBatMode=
Set strBatOFFP=
Set strBatOFNm=
Set strBatNFFP=
Set strBatNFNm=
Set strBatMsgLine0=
Set BatNewFileTargetDir=%BatNewFileTargetDir%
@echo ----------------------------------------------------------------
@echo Process Cmd.%ProCntZeroFill:~-3% for file: %1
@echo Key-in e to exit, r to run, s to skip, n to notepad, t to new target dir :
rem ECHO on
For /f "tokens=1 delims=" %%a in ('cScript //NoLogo %FileToCall% %1') Do %%a
If Not #%strBatMode%#==#BatCopyOldToNewThenEraseOld# GoTo PresentUserChoice
Echo Old File = %strBatOFFP%
dir "%strBatOFFP%"|findstr /i "%strBatOFNm%"
Echo New File = %strBatNFFP%
dir "%strBatNFFP%"|findstr /i "%strBatNFNm%"
:PresentUserChoice
rem :PresentUserChoice
@Set /P BatUserCho=%strBatMsgLine0% - Cmd.%ProCntZeroFill:~-3%:[%BatUserCho%]:
echo :%BatUserCho%:run-now|findstr /i ":R:" && GoTo RunNow
echo :%BatUserCho%:exit-now|findstr /i ":E:" && GoTo DoExit
echo :%BatUserCho%:skip-now|findstr /i ":S:" && GoTo ShiftNow
echo :%BatUserCho%:notepad-now-and-rerun|findstr /i ":N:" && GoTo NotepadNow
echo :%BatUserCho%:set-new-target-dir|findstr /i ":T:" && GoTo SetNewTarget
%echo User Choice: %BatUserCho% not recognized, try again.
GoTo SameAgain
:RunNow
rem :RunNow
If #%strBatMode%#==#BatCopyOldToNewThenEraseOld# GoTo BatCopyOldToNewThenEraseOld
If #%strBatMode%#==#MsgThenExit# GoTo DoExit
If #%strBatMode%#==#BatRenameOldToNew# GoTo BatRenameOldToNew
If #%strBatMode%#==#MsgThenSkip# GoTo ShiftNow
:BatRenameOldToNew
rem :BatRenameOldToNew
dir "%strBatOFFP%"|findstr /i "%strBatOFNm%"
@echo on
rename "%strBatOFFP%" "%strBatNFNm%"
@echo off
dir "%strBatNFFP%"|findstr /i "%strBatNFNm%"
If Not Exist "%strBatNFFP%" GoTo BatRenameOldToNewAndNewNotFound
GoTo ShiftNow
:BatRenameOldToNewAndNewNotFound
rem :BatRenameOldToNewAndNewNotFound
@echo New file not found: "%strBatNFFP%"
@echo ***** This is a rename failure. ******
@echo off
GoTo ShiftNow
:BatRenameOldToNewEnd
rem :BatRenameOldToNewEnd
:BatCopyOldToNewThenEraseOld
rem :BatCopyOldToNewThenEraseOld
dir "%strBatOFFP%"|findstr /i "%strBatOFNm%"
dir "%strBatNFFP%"|findstr /i "%strBatNFNm%"
@echo on
Copy /-Y "%strBatOFFP%" "%strBatNFFP%"
@echo off
dir "%strBatOFFP%"|findstr /i "%strBatOFNm%"
dir "%strBatNFFP%"|findstr /i "%strBatNFNm%"
If Not Exist "%strBatNFFP%" GoTo BatCopyOldToNewAndNewNotFound
@echo on
Erase /P "%strBatOFFP%"
dir "%strBatOFFP%"|findstr /i "%strBatOFNm%"
@echo off
GoTo ShiftNow
:BatCopyOldToNewAndNewNotFound
rem :BatCopyOldToNewAndNewNotFound
@echo New file not found: "%strBatNFFP%"
@echo ***** The Delete process was skipped. ******
:BatCopyOldToNewThenEraseOldEnd
ren :BatCopyOldToNewThenEraseOldEnd
:NotepadNow
rem :NotepadNow
rem Notepad FileName will hold bat file, Start Notepad will move on.
echo on
@rem Start Notepad "%strBatOFFP%"
Notepad "%strBatOFFP%"
@echo off
GoTo SameAgain
:NotepadNowEnd
rem :NotepadNowEnd
:SetNewTarget
rem :SetNewTarget
echo off
echo ===============================================
echo TargetDir=%BatNewFileTargetDir%
echo Key-in your new targer directory on next line or s to skip:
Set /P BatTrialTarget=-New Target :
echo ::%BatTrialTarget%:skip-now|findstr /i "::S:" && GoTo SameAgain
Set BatTrialTarget=%BatTrialTarget:"=%
Set BatTrialTarget=%BatTrialTarget:\\=\%
Set BatTrialTarget=%BatTrialTarget%#:#
Set BatTrialTarget=%BatTrialTarget: #:#=#:#%
Set BatTrialTarget=%BatTrialTarget:\#:#=#:#%
Set BatTrialTarget=%BatTrialTarget:#:#=%
dir "%BatTrialTarget%"|findstr /i "Directory.of" && GoTo GoodTDir
echo This directory not found: "%BatTrialTarget%"
GoTo SetNewTarget
:GoodTDir
rem :GoodTDir
Set BatNewFileTargetDir="%BatTrialTarget%"
GoTo SameAgain
:SetNewTargetEnd
rem :SetNewTargetEnd
:RunNowEnd
rem RunNowEnd
:ShiftNow
rem :ShiftNow
shift
If #:#%1#:#==#:##:# GoTo DoPause
GoTo RunProcess
:DoExit
rem :DoExit
@echo off
rem Comment out with rem the next four lines if not wanted.
echo Call "%Per0%" %1 %2 %3 %4 %5 %6 %7 %8 %9>"%TEMP%\ResumeNext9.bat"
echo Call "%Per0%" %*>"%TEMP%\ResumeAll.bat"
echo To Resume: Call "%TEMP%\ResumeNext9.bat"
echo Or Resume: Call "%TEMP%\ResumeAll.bat"
endlocal
ping -n 3 localhost>nul
GoTo DragAndDropDotBatEnd
:DoPause
rem :DoPause
@echo ----------------------------------------------------------------
echo File %Per0%
echo has completed input values [%ProCntZeroFill:~-3%]
@echo ----------------------------------------------------------------
endlocal
Pause
:DragAndDropDotBatEnd
'''DragAndDropTrim12Add_clean.vbs
'''Rev 1.1 11/10/2013 to add optional user specified target directory.
'''Problem Statement: http://stackoverflow.com/questions/11760911/
'''batch-file-that-trims-leading-characters-and-lets-me-save-where-i-want
'''I have (and will have) several text files that need the first 12 characters
'''trimmed from the front of every line. Ideally, I'd like a batch file where
'''I input the name and path of the file, the script runs, the file keeps its
'''same name and location, or same location and you add a "_clean" on the end
'''of the file name. Or, I drop the txt file on the batch file either one of
'''the 2 things described above happens.
'''Is this possible?
'''Assuming the existing Directory and File structures look like this:
'''x:\aaa\bbb\c c\2013_11_05_aMyTextFile 05.txt
'''x:\aaa\bbb\c c\2013_11_05_aMyTextFile001.txt
'''x:\aaa\bbb\c c\2013_11_05_aMyTextFile002.txt
'''x:\aaa\bbb\c c\2013_11_05_aMyTextFile003.txt
'''x:\aaa\bbb\c c\2013_11_05_aMyTextFile004.txt
'''x:\aaa\bbb\c c\2013_11_05_bMyTextFile002.txt
'''And you want then to look like this:
'''x:\aaa\bbb\c c\MyTextFile 05_clean.txt
'''x:\aaa\bbb\c c\MyTextFile001_clean.txt
'''x:\aaa\bbb\c c\MyTextFile002_clean.txt
'''x:\aaa\bbb\c c\MyTextFile003_clean.txt
'''x:\aaa\bbb\c c\MyTextFile004_clean.txt
'''And supporting scripts are:
'''x:\Scripts\DragAndDrop.bat
'''x:\Scripts\DragAndDropTrim12Add_clean.vbs
'''To use from File Explorer:
'From File Explorer, highlight the existing files, then right click and choose "Copy" –
'''then drop (paste) them onto x:\Scripts\DragAndDrop.bat
'''This will walk you through the renaming processes.
'DragAndDrop.bat will call DragAndDropTrim12Add_clean.vbs and invoke the following
''' Check processes:
'''1 DragAndDropTrim12Add_clean.vbs is called in CScript mode.
'''2 Script command line values are being passed from bat file to vbs file
'''3 Modified values are passed back to bat file and set by the For loop.
'''4 New trimmed and appended file name does not conflict with an existing file.
'''5 Files passed on the drop-generated command line still exist.
'''6 File to be processed does not already contain the "_clean" string
'''7 File to be processed can support having 12 characters trimmed.
'''8 As each file is processed, the script gives several "User Choice" options.
'''Bat File Values to pass
'''Set strBatMode=MsgThenExit,MsgThenSkip,BatCopyOldToNewThenEraseOld,BatRenameOldToNew
'''Set strBatOFFP=strOldFileFullPath
'''Set strBatOFNm=strOldFileName
'''Set strBatNFFP=strNewFileFullPath
'''Set strBatNFNm=strNewFileName
'''Set strBatMsgLine0=Note:Do not use double quote.
Option Explicit ''Requires that you dimension all variables
Dim funInStrVal, funLastHitVal, StdOut, StdErr, objFSO, strWScriptArg0
Dim intLastHit, intLenMinus, intTrimLeadNum, strTrailString
Dim objDialog, intReturn, strMsg1, strNewFileFullPath, strNFN, strTrS
Dim strOldFileFullPath, strOldFilePath, strOldFileName, strOldFileNameNoExt
Dim strNewFileName, strS, wshShell, strBatNewFileTargetDir
If InStr(1,LCase(WScript.FullName),"cscript.exe",1) = 0 Then
Dim objShell, Rsp01
Set objShell = WScript.CreateObject("WScript.Shell")
Rsp01 = objShell.Popup("This script must be run using cScript" _
& vbCrLf & "Error from " & Wscript.ScriptFullName & vbCrLf _
& "Use: cScript //NoLogo """ & Wscript.ScriptFullName _
& """",10," Error Because Not Using cScript " _
& "(10 sec timeout)",vbOKOnly + vbCritical)
Set objShell = Nothing
Wscript.Quit
End If
intTrimLeadNum = 12
strTrailString = "_clean"
''Set StdIn = WScript.StdIn
Set StdOut = WScript.StdOut
Set StdErr = WScript.StdErr
Set wshShell = CreateObject( "WScript.Shell" )
strBatNewFileTargetDir = wshShell.ExpandEnvironmentStrings( "%BatNewFileTargetDir%" )
Set wshShell = Nothing
strBatNewFileTargetDir = Replace(strBatNewFileTargetDir,"""","") ''remove dq
If WScript.Arguments.Count > 0 Then
strWScriptArg0=Trim(WScript.Arguments.Item(0))
Else
strMsg1="NO Command Line" _
& " value passed to: " & Wscript.ScriptFullName
StdErr.WriteLine "WARNING: " & strMsg1
StdOut.WriteLine "Set BatUserCho=E"
StdOut.WriteLine "Set strBatMode=MsgThenExit"
StdOut.WriteLine "Set strBatMsgLine0=.........................Press Enter to Exit"
Wscript.Quit
End If
Set objFSO = CreateObject("Scripting.FileSystemObject")
If objFSO.FileExists(strWScriptArg0) = False Then
strMsg1 = strWScriptArg0 & " is not a valid file name."
StdErr.WriteLine "WARNING: " & strMsg1
StdOut.WriteLine "Set BatUserCho=S"
StdOut.WriteLine "Set strBatMode=MsgThenSkip"
StdOut.WriteLine "Set strBatMsgLine0=.........................Press Enter to Skip"
Set objFSO = Nothing
Wscript.Quit
End If
strOldFileFullPath = strWScriptArg0
strOldFilePath = FunLeftOrRtStr(strOldFileFullPath, "\", "L")
strS = strOldFileFullPath ''Short String for using less columns
strOldFileName = Right(strS,Len(strS) - (FunLastHitInt(strS, "\") + 1))
strOldFileNameNoExt = Trim(FunLeftOrRtStr(strOldFileName, ".", "L"))
strNFN=strOldFileNameNoExt
strTrS=strTrailString & "." & FunLeftOrRtStr(strOldFileName, ".", "R")
If Len(strOldFileNameNoExt) <= intTrimLeadNum Then
strMsg1 = strOldFileFullPath & " Base File Name is:" & vbCrLf & Len(strOldFileNameNoExt) _
& " characters which is too short for the " & intTrimLeadNum & " char trim."
StdErr.WriteLine "WARNING: " & strMsg1
StdOut.WriteLine "Set BatUserCho=S"
StdOut.WriteLine "Set strBatMode=MsgThenSkip"
StdOut.WriteLine "Set strBatMsgLine0=.........................Press Enter to Skip"
StdOut.WriteLine "Set strBatOFFP=" & strOldFileFullPath
StdOut.WriteLine "Set strBatOFNm=" & strOldFileName
Set objFSO = Nothing
Wscript.Quit
End If
''Remove any leading or trailing white space with Trim()
strNewFileName = Trim(Right(strNFN, Len(strNFN) - intTrimLeadNum)) & strTrS
StdErr.WriteLine "strBatNewFileTargetDir=" & strBatNewFileTargetDir
If strBatNewFileTargetDir = "UseOldFilePath" Or InStr(1,strBatNewFileTargetDir, "\") = 0 Then
strNewFileFullPath = strOldFilePath & "\" & strNewFileName
Else
strNewFileFullPath = strBatNewFileTargetDir & "\" & strNewFileName
End If
If objFSO.FileExists(strNewFileFullPath) = True Then
StdErr.WriteLine "WARNING: " & strNewFileName & " existing."
StdOut.WriteLine "Echo You can Copy Old and overwrite Existing"
StdOut.WriteLine "Echo You will be prompted for the Overwrite:"
StdOut.WriteLine "Echo You will also be prompted for the Delete:"
StdOut.WriteLine "Set strBatMode=BatCopyOldToNewThenEraseOld"
StdOut.WriteLine "Set BatUserCho=R"
StdOut.WriteLine "Set strBatMsgLine0=..Press Enter to Copy Old to New Then Delete Old"
StdOut.WriteLine "Set strBatOFFP=" & strOldFileFullPath
StdOut.WriteLine "Set strBatOFNm=" & strOldFileName
StdOut.WriteLine "Set strBatNFFP=" & strNewFileFullPath
StdOut.WriteLine "Set strBatNFNm=" & strNewFileName
Set objFSO = Nothing
Wscript.Quit
Else
StdOut.WriteLine "Echo Old File = " & strOldFileFullPath
If InStr(1,strOldFileName, strTrailString) > 0 Then
strMsg1 = strOldFileName & " already contains: " & strTrailString
StdErr.WriteLine "***WARNING: " & strMsg1 & "***"
StdOut.WriteLine "Echo New File Would = " & strNewFileFullPath
StdOut.WriteLine "Set BatUserCho=S"
StdOut.WriteLine "Echo...........Key-in r to RUN and Rename Old to New. "
StdOut.WriteLine "Set strBatMsgLine0=................... or Press Enter to Skip"
Else
StdOut.WriteLine "Echo New File = " & strNewFileFullPath
StdOut.WriteLine "Set BatUserCho=R"
StdOut.WriteLine "Set strBatMsgLine0=...........Rename Old to New---Press " _
& "Enter to RUN"
End If
StdOut.WriteLine "Set strBatMode=BatRenameOldToNew"
StdOut.WriteLine "Set strBatOFFP=" & strOldFileFullPath
StdOut.WriteLine "Set strBatOFNm=" & strOldFileName
StdOut.WriteLine "Set strBatNFFP=" & strNewFileFullPath
StdOut.WriteLine "Set strBatNFNm=" & strNewFileName
End If
If 1 = 2 Then ''''Change to 1 = 1 for testing. StdErr will not go to bat file
Dim strInVal, strTFileName, strTNewFile, strTFileNameNoExt, strTFileExt
''strInVal = "X:\aaa\bbb\c c\12345.678"
strInVal = strWScriptArg0
intLastHit = FunLastHitInt(strInVal, ".")
StdErr.WriteLine " : strInVal=" & strInVal
StdErr.WriteLine " : Path+File=" & Left(strInVal,intLastHit)
StdErr.WriteLine " : Ext=" & Right(strInVal,Len(strInVal) - intLastHit)
StdErr.WriteLine " : Path=" & FunLeftOrRtStr(strInVal, "\", "L")
StdErr.WriteLine " : FileName=" & FunLeftOrRtStr(strInVal, "\", "R")
strTFileName=Right(strInVal,Len(strInVal) - (FunLastHitInt(strInVal, "\") + 1))
strTFileNameNoExt = FunLeftOrRtStr(strTFileName, ".", "L")
strTFileExt="." & FunLeftOrRtStr(strInVal, ".", "R")
StdErr.WriteLine " : FileNameNoExt=" & strTFileNameNoExt
StdErr.WriteLine " : Ext=" & strTFileExt
strTNewFile=Right(strTFileNameNoExt, Len(strTFileNameNoExt) - intTrimLeadNum)
StdErr.WriteLine " : NewFile=" & strTNewFile & strTrailString & strTFileExt
End If ''If 1 = 2 Then
Function FunLastHitInt(funInputString, funHitChar)
'''Dim funInStrVal, funLastHitVal (Required at top of script)
'''For Dir Use: Left(strFullPath,FunLastHitInt(strFullPath, "\"))
''For File Use:
''Right(strFullPath,Len(strFullPath) - (FunLastHitInt(strFullPath, "\") + 1))
If InStr(1,funInputString, funHitChar) > 0 Then
funInStrVal = 2
Do Until funInStrVal = 1 ''funLastHitVal will eventually = 0 + 1
funLastHitVal = InStr(funInStrVal, funInputString, funHitChar)
If funLastHitVal > 0 Then
FunLastHitInt = funLastHitVal - 1
End If
funInStrVal = funLastHitVal + 1
''Wscript.Echo "funLastHitVal=" & funLastHitVal
Loop
Else
FunLastHitInt = 0
End If
End Function ''Function FunLastHitInt(funInputString, funLastChar)
Function FunLeftOrRtStr(funFullPathLR, funHitCharLR, funLorR)
If InStr(1,funFullPathLR,funHitCharLR) = 0 Then
FunLeftOrRtStr = funFullPathLR
ElseIf UCase(funLorR) = "R" Then
intLenMinus = (FunLastHitInt(funFullPathLR, funHitCharLR) + Len(funHitCharLR))
FunLeftOrRtStr = Right(funFullPathLR,Len(funFullPathLR) - intLenMinus)
Else
FunLeftOrRtStr = Left(funFullPathLR,FunLastHitInt(funFullPathLR, funHitCharLR))
End If
End Function
Set objFSO = Nothing
Wscript.Quit
'''DragAndDropTrim12Add_clean.vbsEnd