前言
有些软件留了接口,可以直接在cmd或者powershell中完成某些功能。这样做批处理时很方便。
先记录一些cmd和powershell的文档,有些cmd的命令在powershell上竟然不兼容,比如很好用的/?
参数。
后面利用cmd完成了一个压缩包重命名的功能。
cmd相关语法
参考:Windows CMD命令大全
参考:批处理脚本教程
@echo off
setlocal EnableDelayedExpansion
::@强制关闭回显
::和rem的区别是,rem会回显,::则不会。
REM 关闭后不回显,否则显示每条命令,在输出结果
REM echo "cmd test!"
REM pause
echo "命令测试"
echo.
REM %行中注释,慎用。echo. 输出空行%
echo.
REM 管道命令,用于回复
echo.|time
echo something>filename
echo anotherthing>>filename
type filename
REM 0-Success, 1-Failed.
echo %errorlevel%
REM title set_title_name
title title_now
REM set color: 0-9-f
color 01
REM set system devices
mode con cols=120 lines=30 & color 01
REM jump to the label.
goto label
echo label
:label
REM FIND [/V] [/C] [/N] [/I] [/OFF[LINE]] "string" [[drive:][path]filename[ ...]]
find /n "string" filename
type filename | find /n "thing"
REM explorer D:
REM start explorer D:
REM goto label
Call :label2
echo "call test again"
REM call try.bat
if errorlevel 1 (
Echo 产生一个临时文件 > tmp.txt
Rem 下行先保存当前目录,再将c:\windows设为当前目录
pushd D:\Myprogram\Other\
Call :sub tmp.txt
Rem 下行恢复前次的当前目录
Popd
Call :sub tmp.txt
pause
Del tmp.txt
)
if "abc"=="abc" (
if [abc] == [abc] (
if {abc} == {abc} (
if not exist tmp.txt (
echo "the file not exist!"
) else (
echo "The file exists!"
)
)
)
)
REM setlocal与变量延迟,按行处理,下一条生效
REM 交换两变量
set value1=123
set value2=abc
echo before:value1=%value1%,value2=%value2%
set value1=%value2%& set value2=%value1%
echo after:value1=%value1%,value2=%value2%
REM netstat -n -p tcp
REM format aaa: /s /q
REM dir G:\ || dir D:\ || dir E:\ && dir G:\ & dir F:\
REM for /d %%i in (c:\*) do echo %%i
for /r D:\adb %%x in (*exe) do echo %%x
REM for /r d:\adb %%x in (adb.exe) do if exist %%x echo %%x
REM for /l %%i in (5,-1,1) do echo %%i
REM FOR /F "eol=; tokens=1,3* delims=,- " %%i in (test.txt) do echo %%i %%j %%k
REM for /f "delims==" %i in ('dir /b') do echo %~fi
REM for /f "delims=" %i in ("code.cmd") do echo %~$PATH:i
REM %0 实现无限循环调用
REM set /p value=Input the value:
REM set /a var+=1 表示运算表达式
REM 截取:%value:~0,3%从下表0开始,长度为3
REM delay: ping/for/
REM 1;ms延时,误差1000ms
REM :delay
REM echo WScript.Sleep %1>delay.vbs
REM CScript //B delay.vbs
REM del delay.vbs
REM goto :eof
REM 2;10ms延时,误差50ms
call :delay2 1000
REM %random%%%(%max%-%min%+1)+%min%
set /a abc=%RANDOM%%%10+1
for /l %%i in (1,1,10) do (
echo !random!
)
REM 命令嵌套 call "string"
set string=echo ok
call string
REM exit
goto :eof
:label2
echo "this a call test!"
goto :eof
:sub
Echo 删除引号: %~1
Echo 扩充到路径: %~f1
Echo 扩充到一个驱动器号: %~d1
Echo 扩充到一个路径: %~p1
Echo 扩充到一个文件名: %~n1
Echo 扩充到一个文件扩展名: %~x1
Echo 扩充的路径指含有短名: %~s1
Echo 扩充到文件属性: %~a1
Echo 扩充到文件的日期/时间: %~t1
Echo 扩充到文件的大小: %~z1
Echo 扩展到驱动器号和路径:%~dp1
Echo 扩展到文件名和扩展名:%~nx1
Echo 扩展到类似 DIR 的输出行:%~ftza1
Echo.
Goto :eof
:delay
REM set /p delay=请输入需延迟的毫秒数:
set delay=%1
set TotalTime=0
set NowTime=%time%
::读取起始时间,时间格式为:13:01:05.95
REM echo 程序开始时间:%NowTime%
:delay_continue
set /a minute1=1%NowTime:~3,2%-100
::读取起始时间的分钟数
set /a second1=1%NowTime:~-5,2%%NowTime:~-2%0-100000
::将起始时间的秒数转为毫秒
set NowTime=%time%
set /a minute2=1%NowTime:~3,2%-100
:: 读取现在时间的分钟数
set /a second2=1%NowTime:~-5,2%%NowTime:~-2%0-100000
::将现在时间的秒数转为毫秒
set /a TotalTime+=(%minute2%-%minute1%+60)%%60*60000+%second2%-%second1%
if %TotalTime% lss %delay% goto delay_continue
REM echo 程序结束时间:%time%
REM echo 设定延迟时间:%delay%毫秒
REM echo 实际延迟时间:%TotalTime%毫秒
goto :eof
:delay2
@echo off
if "%1"=="" goto :eof
set DelayTime=%1
set TotalTime=0
set NowTime=%time%
::读取起始时间,时间格式为:13:01:05.95
:delay_continue
set /a minute1=1%NowTime:~3,2%-100
set /a second1=1%NowTime:~-5,2%%NowTime:~-2%0-100000
set NowTime=%time%
set /a minute2=1%NowTime:~3,2%-100
set /a second2=1%NowTime:~-5,2%%NowTime:~-2%0-100000
set /a TotalTime+=(%minute2%-%minute1%+60)%%60*60000+%second2%-%second1%
if %TotalTime% lss %DelayTime% goto delay_continue
goto :eof
:steprunning
echo.
echo ┌──────────────────────────────────────┐
ping 127.0.0.1 >nul /n 1 & set /p=<nul
for /L %%i in (1 1 39) do set /p a=■<nul& ping /n 1 127.0.0.1>nul
echo 100%%
echo └──────────────────────────────────────┘
pause
goto :eof
REM echo %string:~-79,60%
set abc=.\7z.exe l F:\Library\CallioLab\sentinel2\L1C_T31TGL_A019167_20190222T104036.zip | find "manifest.safe"
Powershell相关语法
参考:PowerShell 在线教程
参考:PowerShell教程
# echo off
# Set-ExecutionPolicy Unrestricted
# Get-ExecutionPolicy -List
# Get-ExecutionPolicy -Scope CurrentUser
# Get-Service | Where-Object {$_.Status -eq "stopped"}
# $PSVersionTable
<#
powershell
#>
# $PSCOMMANDPAT
Write-Output "power shell test!"
$myvalue = 110
$myvalue_1 = $true
${mynewvalue} = "filename: $myvalue"
Write-Output $myvalue,$myvalue_1,$mynewvalue
# clear-variable -name value
#支持数组的数据结构,用逗号隔开赋值,或者用范围运算符赋值
# 支持下标访问,也支持类似于切片的访问方式
${num_array} = 10..15
${num_newarray} = 10,11,12,13,14,15
${num_newarray}[1..-1] # 11 10 15
${num_array}[0]
$num_array_length = $num_array.Length - 2
$num_array += $myvalue
$num_array = ($num_array[0..$num_array_length])
# 哈希与字典
$hash_array = @{ name = "hash"; version = 5.0}
$dict_order_array = [ordered] @{name = "Dict"; version = $hash_array['version']+1}
write-host("Print all hashtable keys")
$dict_order_array.keys
$hash_array.values
$dict_order_array.Count
write-host("Add key-value")
$hash_array["Updated"] = "2020-08-18 21:06"
write-host("Add key-value")
$hash_array.Add("Created","Now")
write-host("Remove key-value")
$hash_array.Remove("Updated")
# 运算符,除了支持基本的运算符外,还支持+-*/与=的结合,以及自增运算符
$myvalue = $myvalue++
$myvalue = --$myvalue
if ("filename" -like $mynewvalue) {
Write-Output "Like!"
} elseif ($myvalue -eq 120) {
Write-Output "Equal!"
} elseif ("file" -match $mynewvalue){
Write-Output "Match!"
} elseif (14 -contains ${num_array}) {
Write-Output "contains!"
} elseif (14 -in ${num_array}) {
Write-Output "in!"
} elseif ($myvalue_1 -is [bool]) {
Write-Output "Bool!"
$string_ori = "Windows, Ubuntu, OSx"
$string_ori -replace "OSx", "OSX"
$string_ori
} else {
Write-Output "Else!"
}
# 拆分与合并
$join_test = "power","shell","test!"
$join_string = $join_test -join "--"
$split_string = $join_string -split "-"
$split_string
# 控制结构,条件,分支
switch ($myvalue) {
109 {
Write-Output $myvalue
# break#可选
}
Default {
Write-Output "None"
break
}
}
do {
$myvalue -= 10
Write-Output "Now, the number is: $myvalue"
} until ($myvalue -le 20)
do {
$myvalue += 10
Write-Output "Now, the number is: $myvalue"
} while ($myvalue -lt 120)
for ($i = 0; $i -lt $myvalue; $i += 10) {
Write-Output "Now, the number is: $i"
}
foreach ($item in $num_array) {
Write-Output "Now, the number is: $item"
}
while ($myvalue -gt 20) {
$myvalue -= 10
if ($myvalue -gt 60) {
continue
}
if ($myvalue -lt 40) {
break
}
Write-Output "Now, the number is: $myvalue"
}
# string 分割,拼接等
$new_string = [System.String]::Concat($mynewvalue, $mynewvalue)
$new_string.SubString(3, 7)
$format_string = "{0}--{1}" -f $mynewvalue, $mynewvalue
$format_string.Replace("110", "100")
# function 函数,返回等
function WriteHello {
param (
$mynum
)
Process {
Write-Output "Function test! The value is: $mynum"
}
}
function ReturnTest([int]$num) {
Process {
Write-Output "Return test! The value is: $num"
$num += 100
return $num
}
}
WriteHello($myvalue)
$myvalue = ReturnTest($myvalue)
$myvalue
# try-catch-finally
Write-Output "try-catch-finally"
try {
ReturnTest($myvalue)
} catch {
# Write-Output $Error
Write-Output "Catch test!"
ReturnTest($myvalue)
} finally {
write-output "kill the process!"
exit
}
压缩包重命名
竟然有软件通过文件名来判断文件类型,可你家的产品被人重新打包名字变了,你就不认识了。
重新打包的也是,解压后文件名还是原来的,那你重命名干啥。
思路:根据划线的提升,先用压缩软件列出所有文件名,然后通过管道命令找到需要的字符串,在重命名压缩文件。
问题:提取到字符串后无法直接给某个变量;call也无法执行。
解决方法:先存到某个文档中,在读取出来。call的外部调用执行。
程序:
@echo off
::::
:: 只用到下面的函数,其他的都是测试。
:: :Renamesentinel2函数是重命名,usgs下载的转为欧空局的名字,方便SNAP直接打开::
::::
:: 开启变量延迟
setlocal EnableDelayedExpansion
if "%1" equ "" (
echo Usage: %~nx0 Renamesentinel2/sentinel2output
pause
exit
)
:: 设置文件的各种路径:
:: 解压软件路径zip:7z和好压都可以,参数l是查看压缩包的内容;
:: 压缩文件路径zipfile,会遍历下面的所有文件,可以选一个大的路径;
:: 执行文件路径batname,方便调用;
:: 新文件名文件outputname,保存分析出来的文件名。
:: zipfile2是测试文件
set zip=D:\7z\App\ProgramFiles\7z.exe l
REM set zipfile=F:\NNN
set zipfile=F:\
set zipfile2=F:\L1C_T32TLR_A010244_20190221T102520.zip
set batname=one.bat
set outputname=sentinel22out.txt
set string="manifest.safe"
REM call :Renamesentinel
REM call :Renamesentinel2
call :%1
goto :eof
::尝试
:sentinel2
echo @echo off>one.bat
for /r %zipfile% %%x in (L1C*zip) do (
set file=%%x
REM echo !file!
set filename="%zip% !file! | find %string%>>sentinel2out.txt
echo(!filename:~1!)>>one.bat
REM call !filename:~1!
)
call one.bat
goto :eof
::批量写入到bat文件
:sentinel2output
for /f "delims=" %%j in (sentinel21.txt) do (
REM set file=%%x
REM call %%j >> sentinel2output.txt
echo(@echo off)>one.bat
echo(%%j)>one.bat
)
goto :eof
::测试,从文本中读取命名,批量重写
:Renamesentinel
for /f "delims=" %%i in (%outputname%) do (
set tmp=%%i
set newname=!tmp:~53,60!.zip
echo !newname!>>sentinel2name.txt
)
goto :eof
::Renamesentinel2函数是重命名,usgs下载的转为欧空局的名字,方便SNAP直接打开
:Renamesentinel23
::在zipfile路径下寻找L1C开头的zip结尾的所有文件,返回文件的绝对路径给x
for /r %zipfile% %%x in (L1C*zip) do (
REM echo @echo off>%batname%
set file=%%x
::变量延迟,拼接执行命令,写入到外部batname文件中,在执行
::会把新文件的名字写入到另一个文件中,利用call调用
set filename="%zip% !file! | find %string%>%outputname%
echo !filename:~1!>%batname%
call %batname%
::获取新文件的名字
for /f "delims=" %%i in (%outputname%) do (
set tmp=%%i
set newname=!tmp:~53,60!.zip
REM echo !newname!
)
::利用rename完成文件重命名,源文件给绝对路径,新文件
REM set renamex=!file:~0,-38!!newname!
if not !newname! == "" (
rename !file! !newname!
echo oldname=!file!,newname=!newname!
)
)
REM call one.bat
goto :eof
总结
powershell直接执行可能存在问题,还是要cmd里面跑。后面用powershell写估计就不用这么麻烦了。