目录
使用示例:寻找java的某个进程,并终止这个进程(window bat)
寻找java的某个进程,并终止这个进程(Linux 环境终止)
■扩展3(对扩展2的改进: 查找文件,即 find 代替 findstr)
■扩展4.1 (截取每一行中,从第n(70)位开始,截取m(20)位。 )
■ ★ 扩展4.2 (读取文件,从每一行,从字符中,获取指定的内容 ) ★ 含有 if else 语句
找到指定文件,看大小是否是0size (大小不为0时,返回1)
■扩展11 获得上一条命令的返回值 [ %errorlevel%]
■前言(希望的功能)
批量删除CSV文件第一行的表头,重新写入【新的标头】。
(即,删除第一行的内容后,重新写入新的内容)
■実現
-----------------------------------------------------------------------------------------------------
@setlocal enabledelayedexpansion
@echo off
set newFirstLineStr=%1
set newFirstLineStr2=%newFirstLineStr:""="%
set newFirstLineStr3=%newFirstLineStr2:"空值"=""%
set newFirstLineStr4=%newFirstLineStr3:kkk= %
cd /d %~dp0
set inputdir=c:\data\in
set outputdir=c:\data\out
for /f "delims=" %%i in ('dir /b /s %inputdir%\*.txt') do xcopy /Y %%i %outputdir%
for /f "delims=" %%i in ('dir /b /s %outputdir%\*.txt') do (
set flag=1
for /f "delims=" %%j in ('type %%i') do (
if !flag!==1 (
set flag=0 & echo %newFirstLineStr4%>%%i
) else echo %%j>>%%i
)
)
■実現----------------------------------------------------------------------------------------------------- bug 修正前
(初版bat)VBA调用bat,传入参数(参数内容为西【新的标头】)
(即第一行替换为新的内容,其他行的内容保持不变。)
@setlocal enabledelayedexpansion
@echo off
set newFirstLineStr=%1
cd /d %~dp0
set inputdir=c:\data\in
set outputdir=c:\data\out
for /f "delims=" %%i in ('dir /b /s %inputdir%\*.txt') do xcopy /Y %%i %outputdir%
for /f "delims=" %%i in ('dir /b /s %outputdir%\*.txt') do (
set flag=1
for /f "delims=" %%j in ('type %%i') do (
if !flag!==1 (
set flag=0 & echo %newFirstLineStr:""="%>%%i
) else echo %%j>>%%i
)
)
※ 因为VBA传递进来的参数为 「""1","2","3""」多了一层双引号,所以 要把【连续的两个双引号】替换为【一个双引号】 %str:""="%
※ 【TODO→完了】 bug修正中 中间如果有空项目,“” 也会被替换为一个“ 例:""1","2","3","","5""
↑解决:
VBA代码中,生成字符串的时候,「""1","2","3","空值","5""」
BAT中替换两次
set newFirstLineStr2=%newFirstLineStr:""="%
set newFirstLineStr3=%newFirstLineStr2:"空值"=""%
。。。。
set flag=0 & echo %newFirstLineStr3%>%%i
※ 注意:延期变量使用时,要使用!变量名!
※ 【TODO】 处理源的文件中,如果有换行,并且这个换行是Linux的换行。\n
那么复制后的文件,所有的换行都会变成windows的换行。\r\n
↑影响:处理源文件是CSV文件,CSV文件中,项目如果有行内换行(\n),转换后的CSV文件,再次作为数据投入时,和原有数据不一致。
↑【解决中。。。】windows环境,bat脚本中,使用echo后,如何指定换行符为[\n]-优快云论坛
※ 【TODO→完了】 VBA侧传入的参数带有空格
↑解决:
VBA侧把空格替换成kkk
bat侧再把kkk替换为空格
set newFirstLineStr4=%newFirstLineStr3:kkk= %
VBA中
str = Replace(str, " ", "kkk")
■参考
■参考1
・为文件添加head,body
@echo off
for /f "delims=" %%i in ('type input.txt') do (
if not defined a (
echo head----------- >output.txt
set a=a & echo %%i>>output.txt
echo body----------- >> output.txt
) else echo %%i >>output.txt
)
・效果
・input.txt
11aaa11
11aaa11
222bbb222
333ccc333
6666
・执行bat
生成 output.txt
head-----------
11aaa11
body-----------
11aaa11
222bbb222
333ccc333
6666
■参考2
more /e +1 input.txt> input1.txt
■参考3------------------------------------------------------------------------------------------------------
VBA调用BAT
VBA调用bat,doc 命令行 窗口关闭之后,VBA代码 再继续执行_sun0322-优快云博客
VBA读取文件名
VBA遍历文件夹下文件文件实用源码 - 愚公一山 - 博客园
BAT相关代码
从当前文件夹以及子文件夹中,批量移动指定名字的文件_sun0322-优快云博客
VBA处理文件框架代码 【第二部分:变量定义】_sun0322-优快云博客_vba 框架
bat for 循环中定义变量(变量值不显示,通过使用「延期变量扩展」方式解决)_sun0322-优快云博客
---
■特殊符号
特殊符号【^】
^符号(也称为插入符号或抑扬符)是Batch脚本中的转义字符.使用该字符时,下一个字符将被解释为普通字符.
使用示例:寻找java的某个进程,并终止这个进程(window bat)
@echo off
set path="C:\java\8\8\bin";%path%
for /f "tokens=1" %%a in ('jps -l ^| findstr xxx001.jar') do (
taskkill /f /pid %%a
)
java -jar xxx001.jar
jps命令
jps命令,JPS 是一个Java虚拟机进程状态工具,它用于查看运行在Java虚拟机(JVM)中的所有Java进程。
寻找java的某个进程,并终止这个进程(Linux 环境终止)
ps aux | grep /xxxx/xxxx/xxx001.jar | grep -v grep | awk '{print "kill -9", $2} | sh
===
■扩展1 (VBA实现)
VBA读取指定目录下,任意一个文件,第一行的内容
Dim fileName As String
' 如果有文件,会取出排序第一的文件的名字。(只有文件名,没有目录信息)
fileName = Dir("c:\data\" & "*.csv")
If fileName ="" then
Application.StautsBar = "File Not Found"
Exit sub
end If
Dim oldTitleStr
Open "c:\data\" & fileName For Input As #1
Do While Not EOF(1)
Line Input #1, oldTitleStr
‘ 只读取一行,即退出循环
Exit Do
Loop
Close #1
参照
VBA遍历文件夹下文件文件实用源码 - 愚公一山 - 博客园
■扩展2
获取数组的长度
Dim len As Integer
len = UBound(list) - LBound(list) + 1
--
■扩展2(遍历文件,找到指定字符串,并输出到指定文件中)
※ 数据量大时,不建议使用,
仅仅是处理一个900多K, 2500行的数据,就耗时5分钟左右的时间。
===
注意:第24行的代码需要加上双引号。
(原因,【查询对象字符串】中含有空格, 【查询KEY】中 含有空格)
echo "%%j" | findstr "%MARCH_STR%" >nul && (
===
@setlocal enabledelayedexpansion
@echo off
set newFirstLineStr=%1
cd /d %~dp0
set inputdir=c:\data\in
set outputdir=c:\data\out
set MARCH_STR=XXXX XXXXX XXXXX
echo FIND_KEY:%MARCH_STR%>%outputdir%\result.txt
echo FIND_RESULT:>>%outputdir%\result.txt
for /f "delims=" %%i in ('dir /b /s %inputdir%\*.txt') do xcopy /Y %%i %outputdir%
for /f "delims=" %%i in ('dir /b /s %outputdir%\*.txt') do (
set FIND_FLAG=0
for /f "delims=" %%j in ('type %%i') do (
echo "%%j" | findstr "%MARCH_STR%" >nul && (
set FIND_FLAG=1
) || (
set FIND_FLAG=0
)
if !FIND_FLAG!==1 (
echo %%j>>%outputdir%\result.txt
)
)
)
===
■扩展2(显示读取行数)
注意:bat数字相加式
set /a COUNT=!COUNT!+1
@setlocal enabledelayedexpansion
@echo off
set newFirstLineStr=%1
cd /d %~dp0
set inputdir=c:\data\in
set outputdir=c:\data\out
set MARCH_STR=XXXX XXXXX XXXXX
echo FIND_KEY:%MARCH_STR%>%outputdir%\result.txt
echo FIND_RESULT:>>%outputdir%\result.txt
for /f "delims=" %%i in ('dir /b /s %inputdir%\*.txt') do xcopy /Y %%i %outputdir%
for /f "delims=" %%i in ('dir /b /s %outputdir%\*.txt') do (
set FIND_FLAG=0
set COUNT=0
for /f "delims=" %%j in ('type %%i') do (
set /a COUNT=!COUNT!+1
echo !COUNT!
echo "%%j" | findstr "%MARCH_STR%" >nul && (
set FIND_FLAG=1
) || (
set FIND_FLAG=0
)
if !FIND_FLAG!==1 (
echo %%j>>%outputdir%\result.txt
)
)
)
===
■扩展3(对扩展2的改进: 查找文件,即 find 代替 findstr)
type xxx.log | find "XXX XXX XX" >result.txt
■扩展3(直接使用findstr,以文件单位,进行检索)
使用 下面 命令时,有时会出现乱码问题,而且是随机(Random)在某一行出现。
type xxx.log | find "XXX XXX XX" >result.txt
出现原因未知,所以还可以使用下面的代码,进行查询。
findstr /R "AAABBBCCC.*ID.*ID" xxx.log>result.txt
参数 /R 代表支持正则表达式
・findstr中 的 SearchKey不支持汉字
findstr /R "SearchKey" c:/AAA/BBB/DDD/YourFile.txt
・SearchKey不支持汉字
・chcp 65001 查询 UTF-8 的文件时,一个汉族占8个字符
・排除指定位置,我们不想查询的行 (AAAAA大B)
findstr /R "AAAAA...[^B]"
===
■扩展4 对某个文件中的内容进行替换 (可以多次替换)
@echo off
chcp 65001
rem delims为字符串 eol=# 忽略以#开头的行 tokens=1-10* 从第1组到10*
rem 括号里填写你要替换的文件
(for /f "delims=" %%a in (a.txt) do (
rem 将一个值赋给一个变量
set "str=%%a"
setlocal enabledelayedexpansion
rem 旧字符串=新字符串
set "str=!str:wwww2=1111!"
set "str=!str:wwww3=2222!"
set "str=!str:wwww4=3333!"
echo,!str!
endlocal
))>"112.txt"
rem 先把(已经完成替换)好的文件替换旧文件
move /y "112.txt" "a.txt"
■扩展4.1 (截取每一行中,从第n(70)位开始,截取m(20)位。 )
(适用于每行格式都相同文件)
@echo off
chcp 65001
cd %~dp0
(for /f "delims=" %%a in (101_Grep.txt) do (
set "str=%%a"
setlocal enabledelayedexpansion
set "str=!str:~70,20!"
echo,!str!
endlocal
))>"101.txt"
■ ★ 扩展4.2 (读取文件,从每一行,从字符中,获取指定的内容 ) ★ 含有 if else 语句
读取对象文件,想得到黄色标记的内容,但是因为ID的位数不同,造成 想要抽出字符串的开始位置不同
====
aaaabbbb id=123 cccccdddddeee 1234567891.csv aaabbbbbccc variable1
aaaabbbb id=124 cccccdddddeee 1234567892.csv aaabbbbbccc variable1
aaaabbbb id=1245 cccccdddddeee 1234567893.csv aaabbbbbccc variable1
aaaabbbb id=12467 cccccdddddeee 1234567894.csv aaabbbbbccc variable1
aaaabbbb id=124678 cccccdddddeee 1234567894.csv aaabbbbbccc variable1
原始处理代码
@echo off
chcp 65001
cd %~dp0
(for /f "delims=" %%a in (101_Grep.txt) do (
set "str=%%a"
setlocal enabledelayedexpansion
set "flgChar=!str:~43,1!"
set "str=!str:~30,10!"
echo,!str!
endlocal
))>"101.txt"
原始处理代码得到的结果
1234567891
1234567892
123456789
e 12345678
ee 1234567
改进后的处理代码
@echo off
chcp 65001
cd %~dp0
(for /f "delims=" %%a in (101_Grep.txt) do (
set "str=%%a"
setlocal enabledelayedexpansion
set "flgChar=!str:~43,1!"
if !flgChar!==v (
rem id 3 位
set "str=!str:~30,10!"
) else if !flgChar!==s (
rem id 4 位
set "str=!str:~31,10!"
) else if !flgChar!==c (
rem id 5 位
set "str=!str:~32,10!"
) else if "!flgChar!"=="." (
rem id 6 位
set "str=!str:~33,10!"
) else (
set "str=Message。。。"
)
echo,!str!----!flgChar!
endlocal
))>"101.txt"
改进后的处理代码得到的结果
1234567891----v
1234567892----v
1234567893----s
1234567894----c
1234567894----.
■扩展5 合并文件
@echo off
setlocal enabledelayedexpansion
copy *.csv newFile.csv
pause
■扩展5 合并文件(另外一种方式)
使用 下面这种方式合并,在合并后文件的最后一行,会有一个未知的特殊字符。
copy *.csv newFile.txt
所以,还可以使用下面这种方式合并文件
rem first line is blank
rem echo=>newfile.txt
rem real 0 size file
type nul>newfile.txt
for /f "delims=" %%i in (11.csv) do (
echo %%i>>newfile.txt
)
for /f "delims=" %%i in (12.csv) do (
echo %%i>>newfile.txt
)
for /f "delims=" %%i in (13.csv) do (
echo %%i>>newfile.csv
)
....
===
■扩展6 去掉重复的行
(文件大时,速度比较慢,3000行,(工作的开发环境)三分钟左右)
A.txt 中有重复的数据
输出到B.txt中,从而去掉重复的数据
@echo off
cd %~dp0
for /f "delims=" %%i in (%~dp0\A.txt) do (
find "%%i" B.txt||echo %%i>>B.txt
)
(升级使用)查找行中,没有重复的内容
最后6位,如果有重复的,只保留1行。
@echo off
cd %~dp0
for /f "delims=" %%i in (%~dp0\A.txt) do (
setlocal enabledelayedexpansion
rem The last 6 bit is not repeat
set "str=%%i"
set "str=!str:~-6,6!"
find "!str! B.txt || echo %%i>>B.txt
endlocal
)
■扩展7 字符串处理
截取字符串
@echo off
set ifo=abcdefghijklmnopqrstuvwxyz0123456789
echo 原字符串(第二行为各字符的序号):
echo %ifo%
echo 123456789012345678901234567890123456
echo 截取前5个字符:
echo %ifo:~0,5%
echo 截取最后5个字符:
echo %ifo:~-5%
echo 截取第一个到倒数第6个字符:
echo %ifo:~0,-5%
echo 从第4个字符开始,截取5个字符:
echo %ifo:~3,5%
echo 从倒数第14个字符开始,截取5个字符:
echo %ifo:~-14,5%
pause
替换字符串
@echo off
set aa=伟大的中国!我为你自豪!
echo 替换前:%aa%
echo 替换后:%aa:中国=中华人民共和国%
echo aa = %aa%
set "aa=%aa:中国=中华人民共和国%"
echo aa = %aa%
pause
■扩展8 日期处理
@echo off
set BACK_FROM=%1
set BACK_TO=%2
move %BACK_FROM% %BACK_TO%.BAK[%date:~0,4%%date:~5,2%%date:~8,2%.%time:~0,2%%time:~3,2%%time:~6,2%].xlsx
■扩展9 判断入力内容_是_7位的数字
@echo off
:beginBegin
set /p userId=Please input userId:
if %userId% geq 1000000 (
if %userId% leq 9999999 (
goto:processProcess
) else (
goto:incorectIncorect
)
) else (
goto:incorectIncorect
)
:processProcess
echo process...
pause
goto:beginBegin
:incorectIncorect
echo Please input a 7 bit userId.
goto:beginBegin
■扩展10 判断 文件大小 0 size
判断多个文件,找到并删除0size的文件
for /f "delims=" %%a in ('dir /a-d/b/s') do (
if "%%~za" equ "0" (
echo;"%%a"
del /a /f /q "%%a"
)
)
找到指定文件,看大小是否是0size (大小不为0时,返回1)
for /f "delims=" %%a in ('dir /a-d/b/s %~dp0\AAA\xxx.txt') do (
if "%%~za" equ "0" (
exit /b 0
) else (
exit /b 1
)
)
rem File not Exist
exit /b 2
■扩展11 获得上一条命令的返回值 [ %errorlevel%]
call xxx.bat
set RESULT_FLG=%errorlevel%
■扩展12 显示文件时间信息
dir "C:\aaa\xxx.txt" | findstr ":*.txt"
■课题
type:结果可能有乱码(发生的位置随机)
type c:/test/log/xxx.log | find "XXX处理执行"
findstr:不支持汉字
findstr /R "aabbb.*.ID.*ccc" c:/test/log/xxx.log
/R 代表查询时,支持正则表达式
■其它
bat各种命令总结(大篇幅)
常用 doc bat 命令总结_sun0322的博客-优快云博客_xcopy只复制文件不复制文件夹
----
For循环命令使用说明
BAT批处理文件 for命令详解_bat for-优快云博客
1.FOR
在cmd窗口中:for %I in (command1) do command2
在批处理文件中:for %%I in (command1) do command2
@echo off
for %%i in (*.txt) do echo %%i
pause>nul
显示当前目录下,所有txt文件
@echo off
for %%i in (a b c d e) do echo %%i
pause>nul
out
a
b
c
d
e
===
2.FOR /L
FOR /L %variable IN (start,step,end) DO command [command-parameters]
@echo off
for /L %%a in (1 2 1000) do echo %%a
pause>nul
这个用法很简单,没有什么要讲解的,从这段代码主要是看出了逗号可以省略.
==
循环生成多个文件
chcp 936
G:
cd G:\Name\日语
for /L %%a in (100001 1 100950) do (
copy 946_日语.docx %%a_日语.docx
)
====
3.FOR /R
FOR /R [[drive:]path] %variable IN (set) DO command [command-parameters]
===
4.FOR /D
FOR /D %variable IN (set) DO command [command-parameters]
如果集中包含通配符,则指定与目录名匹配,而不与文件
====
★5.FOR /F
这个参数/f将会打开(集)里的文件,使for命令能处理文本文件的读取和添加删除替换等编辑性的操作,可谓功能强大,因此也相对复杂一些。
for /f "skip=1 tokens=1,4 delims= " %c in (d:\abc.txt) do @echo %c %d
skip // 表示文本开始忽略的行数为1 ——忽略几行
skip=1 表示文本开始忽略的行数为1 ——忽略几行
tokens // 最多只需取哪几段
tokens=1,4 这个等号后的数字表示依次取第几个被分隔的字符串段,来分别赋给%变量及顺序附加的变量,本例取第1个段赋给%c,第4个段赋给c后的一个变量也就是赋给%d,
delims // 用什么刀来切分
按照空格分割
-----
【IN】
姓名 性别 年龄 等-级
张三 男 36 A-1
李四 男 29 B-2
赵六 女 31 A-2
【OUT】
张三 A-1
李四 B-2
赵六 A-2
------
■植物大战僵尸(修复bat)
D:\植物大战僵尸模式全开版
@echo off
set result=%~dp0PlantsVsZombies.exe
echo 当前目录:%result%
if exist "%result%" (
REG ADD "HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers" /v "%result%" /t REG_SZ /d "WINXPSP3" /f
REG ADD "HKCU\Software\PopCap\PlantsVsZombies" /v ScreenMode /t REG_DWORD /d 0 /f
) else (
echo 文件修复失败请将本程序放到游戏安装目录里面运行
)
===