[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[问题求助] powershell从零开始,学习笔记

感慨,powershell入门真难,我准备在这个帖子将学习过程记录下来。
期待高人路过顺手指点。

powershell难在哪里?
批处理命令学起来相当简单,论坛一日一教学,每个命令怎么用,有哪些参数,清清楚楚;powershell教程里,看起来云里雾里。
打算用powershell刷论坛里新手练功区的题目,以此开始学习。

第一题,生成001--到999之间的数字。
  1. @echo off
  2. for /l %%i in (1001 1 1999) do (
  3.   set var=%%i
  4.   call echo %%var:~-3%%
  5. )
  6. pause
复制代码

本帖最后由 for_flr 于 2021-11-29 14:02 编辑

搜寻得到
  1. $num=1001..1999
复制代码
可以产生1001-1999的序列数字,原以为对每个数字进行字符串截取即可完成.
找到"abcdefg".remove(3,4)这样的字符串截取方法。
却发现不允许$num.remove(0,1)这样的用法。
老实用do循环吧,每个数字前补0即可。
  1. $aa=1
  2. do
  3. {
  4. $bb="{0:d3}" -f ($aa)
  5. $bb
  6. $aa++
  7. }
  8. until($aa -gt 999)
  9. cmd /c pause
复制代码
附上一段powershell字符串处理资料:
  1. 1、字符串格式化
  2.   在说字符串格式化,首先得说单双引号的作用,在powershell中双引号不会屏蔽变量,但单引号会屏蔽,示例如下:
  3. PS C:\> $a = "i have a dream."
  4. PS C:\> Write-Output "this is $a"
  5. this is i have a dream.
  6. PS C:\> Write-Output 'this is $a'
  7. this is $a
  8.   由上述示例我们可以看出,使用单引号会对变量进行转义,而使用双引号则会输出变量的值。
  9.   接下来,再看看字符串格式化的使用,示例如下:  
  10. PS C:\> $a = "i have a dream."
  11. PS C:\> $b = " the variable is $a ,value is {0},there are {1} words" -f $a,4
  12. PS C:\> Write-Output $b
  13. the variable is i have a dream. ,value is i have a dream.,there are 4 words
  14.   字符串格式换中,使用{0},{1},{2}...来代替字符串中变量的位置,-f  后的参数与前面的位置变量相对应。
  15.   接下来我们来探究一下花括号{} 内部的秘密:
  16. 秘密一——固定行宽,即指定每次输入的字符长度,不足的空白补全。
  17. PS C:\> $a = "name"
  18. PS C:\> $b = "age"
  19. PS C:\> $c = "sex"
  20. PS C:\> $d = "{0,-15}{1,-15}{2,-15}"
  21. PS C:\> $d = "{0,-15}{1,-15}{2,-15}" -f $a,$b,$c
  22. PS C:\> Write-Output $d
  23. name           age            sex  
  24.   {0,-15}表示的是第一的变量,占位字符总长度是15,“-”代表左对齐
  25.   【注】{位置,±占位总长},其中“+”代表右对齐,“-”代表左对齐
  26. 秘密二——将数字转换成百分数
  27. PS C:\> "{0:p}" -f 0.31415926
  28. 31.42%
  29. PS C:\> "{0:p3}" -f 0.31415926
  30. 31.416%
  31. PS C:\> "{0:p5}" -f 0.31415926
  32. 31.41593%
  33. PS C:\> "{0:p}" -f "1.23"
  34. 1.23
  35.   百分数转换是用“p”来表示的,默认保留两位有效数字,若“p”后的数字是5,那么就代表保留五位有效数字。
  36.   注意:百分数的转换针对的是整型和浮点型,不能对字符进行转换。
  37. 秘密三——保留几位小数
  38. PS C:\> "{0:n0}" -f 3.1415
  39. 3
  40. PS C:\> "{0:n}" -f 3.1415
  41. 3.14
  42. PS C:\> "{0:n3}" -f 3.1415
  43. 3.142
  44.   n代表要保留几位有效数字,默认是两位有效数字
  45. 2、字符串替换
  46. PS C:\> "i have a dream" -replace "dream","apple"
  47. i have a apple
  48. PS C:\> "i have a dream" -replace "DREAM","apple"
  49. i have a apple
  50. PS C:\> "i have a dream" -creplace "DREAM","apple"
  51. i have a dream
  52. PS C:\> "i have a dream" -creplace "dream","apple"
  53. i have a apple
  54.   字符串替换是“-replace”参数,-replace 可以不区分大小写,而-creplace严格按照大小写来匹配。
  55. 3、包含
  56. PS C:\> "i have a dream" -match "i"
  57. True
  58. PS C:\> "i have a dream" -match "I"
  59. True
  60. PS C:\> "i have a dream" -cmatch "i"
  61. True
  62. PS C:\> "i have a dream" -cmatch "I"
  63. False 
  64. PS C:\> "i have a dream".Contains("have")
  65. True
  66. PS C:\> "i have a dream".Contains("Have")
  67. False
  68.   判断某个字符串是否包含,返回True或False,“-cmatch”严格匹配大小写。
  69.        其实-match的作用不止这些,下一节会提到它的扩展。
  70. 4、过滤器
  71. PS C:\> "3.1415926" -like "3.14*"
  72. True
  73.   “-like”参数支持基本的正则表达式,*代表任意所有,?代表一个字符,.只代表.
  74.   判断字符串的格式是否符合用户所要求的,如上例,“3.14*”表示已以3.14开头的字符,匹配即为True。
  75. 5、字符串分割(将字符串转成列表)
  76. PS C:\> "i have a dream".Split()
  77. i
  78. have
  79. a
  80. dream
  81. PS C:\> "i have a dream".Split("a")
  82. i h
  83. ve
  84. dre
  85. m
  86.   split的作用是将字符串中按照某个字符来分割成列表,默认以空格分割,支持多个分隔符
  87. PS C:\> "http://www.baidu.com".Split('./:')
  88. http
  89. www
  90. baidu
  91. com
  92.   上述例子是将某个字符以“.” “/” “:”来分割,分割出的结果含有两个空白,原因是“/”和“:”都是分隔符,当分割了“:”后,http会与之后的字符分为两行,此时用需要用“/”来分割,在此基础上再次分割,因此产生了空白行,空白行的取消方法如下:
  93. PS C:\> "http://www.baidu.com".Split('./:',[StringSplitOptions]::RemoveEmptyEntries)
  94. http
  95. www
  96. baidu
  97. com
  98.  6、字符串比较  
  99. PS C:\> "i have a dream ".CompareTo("i have a dream")
  100. 1
  101. PS C:\> "i have a dream ".CompareTo("i have a dream ")
  102. 0
  103. PS C:\> "i have a dream ".CompareTo("i have a Dream ")
  104. -1
  105.   字符串比较不支持“-CompareTo”,使用方法是“.CompareTo”,严格区分大小写,完全一致才返回“0”。
  106. 7、字符串的长度
  107. PS C:\> "i have a dream".Length
  108. 14
  109. 8、插入新的字符串
  110. PS C:\> "i have a dream".Insert(9,"new ")
  111. i have a new dream
  112.   Insert的使用方法,在某个位置插入什么字符串,字符串的第一个字符的下标是0,从0开始算起,上述例子,在下位为(9+1)的位置插入“new ”字符串
  113. 9、删除指定的字符串
  114. PS C:\> "i have a dream".Remove(9,5)
  115. i have a
  116.   同上述例子,下标从0开始,在某个位置删除几个字符。
  117. 10、将多个字符串按特定规则组成一个
  118. PS C:\> "i","have","a","dream" -join(" ")
  119. i have a dream
  120.   上述例子是将多个字符串以空格分割组成,同样也可以以其他符合组合,比如:
  121. PS C:\> "10","20","30" -join(":")
  122. 10:20:30 
复制代码

TOP

第二题,去除歌曲编号(重命名)
  1. ::测试环境生成
  2. @echo off
  3. md 测试目录
  4. cd 测试目录
  5. del/q *
  6. cd.>"001 - 萨顶顶 - 万物生.mp3"
  7. cd.>"002 - 萨顶顶 - 神香.wma"
  8. cd.>"003 - 邓丽君 - 月亮代表我的心.mp3"
  9. cd.>"011 - 戴娆 - 绽放.mp3"
  10. cd.>"010 - 梦之旅 - 铃儿响叮当.mp3"
  11. cd.>"007 - 卓依婷 - 捉泥鳅.mp3"
  12. cd.>"009 - 周杰伦 - 稻香.wma"
  13. cd.>"005 - Lene - Pretty Young Thing.wma"
  14. cd.>"029 - M2M - The Day You Went Away.mp3"
复制代码
wp3格式和wma格式歌曲,去除歌曲名字前面的编号,只剩歌名、歌手
批处理可以这样写:
  1. @echo off
  2. for /f "delims=" %%a in ('dir /b /a-d *.mp3 *.wma') do (
  3.     for /f "tokens=1,2,3 delims=-" %%i in ("%%~na") do (
  4.         ren "%%~a" "%%j - %%k%%~xa"
  5.     )
  6. )  
复制代码

TOP

本帖最后由 for_flr 于 2021-11-25 11:26 编辑

powershell可以这样写
  1. get-childitem -path .\* -include *.wma,*.mp3|rename-item -newname{
  2. $_.name.remove(0,$_.name.indexof("-")+1)
  3. }
复制代码
思路是用.indexof("-")返回第一个分隔符-所在文件名长度位置,然后用.remove()将那段长度删除。
搜索资料隐约确定,-filter只能有一个参数,-include可以跟多个参数。
用-include参数,路径用\*
$_ 类似于批处理中的%%a
本帖记录学习过程,个中错误,望指正。
——————————
根据下一楼资料,如果要获取歌曲名称,删除编号和歌手,可以用lastindexof()获取分隔符最后出现的位置,用substring()截取字符串
  1. get-childitem -path .\* -include *.wma,*.mp3|rename-item -newname{
  2. $_.name.substring($_.name.lastindexof("-")+1)
  3. }
复制代码

TOP

下面给出String对象的所有方法:

函数        描述        示例
CompareTo()        与另一个字符串比较        (“Hello”).CompareTo(“Hello”)
Contains()        是否包含制定子串        (“Hello”).Contains(“ll”)
CopyTo()        拷贝子串至新字符串中        $a = (“HelloWorld”).toCharArray()(“User!”).CopyTo(0, a, 6, 5)a,6,5)a
EndsWith()        是否以制定子串结尾        (“Hello”).EndsWith(“lo”)
Equals()        是否与另一个字符串相同        (“Hello”).Equals($a)
IndexOf()        返回第一次匹配的所索引        (“Hello”).IndexOf(“l”)
IndexOfAny()        返回字符串中任意字符的首次匹配索引        (“Hello”).IndexOfAny(“loe”)
Insert()        在指定位置插入字符串        (“HelloWorld”).Insert(6,”brave “)
GetEnumerator()        枚举字符串中所有字符        (“Hello”).GetEnumerator()
LastIndexOf()        字符的最后匹配位置        (“Hello”).LastIndexOf(“l”)
LastIndexOfAny()        任意字符的最后匹配位置        (“Hello”).LastIndexOfAny(“loe”)
PadLeft()        左边补齐空白是字符串至指定长度        (“Hello”).PadLeft(10)
PadRight()        右边填充空白是字符串至指定长度        (“Hello”).PadRight(10) + “World!”
Remove()        从指定位置开始移除指定长度        (“PsTips”).Remove(2,2)
Replace()        替换指定字符串        (“PsTips”).replace(“Ps”,”PS1″)
Split()        以指定分隔符切割字符串        (“HelloWorld”).Split(“l”)
StartsWith()        是否以指定子串开始        (“HelloWorld”).StartsWith(“He”)
Substring()        从指定位置取指定长度子串        “HelloWorld”).Substring(4,3)
ToCharArray()        转换成字符数组        (“HelloWorld”).toCharArray()
ToLower()        转换成小写        (“HelloWorld”).toLower()
ToLowerInvariant() 以区域规则转换成小写        (“HelloWorld”).ToUpperInvariant()
ToUpper()        转换成大写        (“HelloWorld”).ToUpper()
ToUpperInvariant() 以区域规则转换成大写        (“HelloWorld”).ToUpperInvariant()
Trim()        移除字符串前后空格        (” HelloWorld “). Trim()
TrimEnd()        移除字符串结尾的空格        (“HelloWorld “). TrimEnd()
TrimStart()        移除字符串开始的空格        (” HelloWorld”). TrimStart()
Chars()        返回指定位置的字符        (“Hello”).Chars(0)
1

评分人数

    • idwma: 感谢分享技术 + 1

TOP

本帖最后由 for_flr 于 2021-11-30 09:11 编辑

字符串对象的方法太多,处理字符串上肯定是比cmd厉害。英语不好的同学,记忆起来挑战很大。
新手练功区第三、四、五题可以一起练习了。
三,批处理字符串替换
  1. set w=www.bathome.net
  2. set w=%w:bathome=powershell%
  3. echo;%w%
复制代码
powershell字符串替换
  1. $w="www.bathome.net"
  2. $w=$w.replace("bathome","powershell")
  3. $w
  4. write-host $w
复制代码
四,将“今日明月在”显示为“明月今日在”
  1. @echo off
  2. set "s=今日明月在"
  3. echo %s:~2,-1%%s:~0,2%%s:~-1,1%
  4. pause>nul&exit /b
复制代码
powershell还是用substring()
  1. $s="今日明月在"
  2. $s.substring(2,2)+$s.substring(0,2)+$s.substring(4,1)
复制代码
powershell打字量颇多......  对了,可以按TAB键自动补充命令输入。
五,简易密码登录
批处理一般这样写
  1. @echo off
  2. set pwd=123456
  3. set /p in=输入密码:
  4. if "%pwd%" equ "%in%" ( echo;密码正确 ) else ( echo;密码错误 )
  5. pause>nul
复制代码
powershell跟批处理一模一样。
set /p a=    等于  $a=read-host
echo;123         等于  write-host "123"
  1. $pwd=123456
  2. $in=read-host "输入密码:" -assecurestring
  3. #-assecurestring 参数,会用*符号掩盖用户输入的字符,secure安全,as介词“作为”,string字符串。所以我把这个参数记忆成“作为安全字符串”,哈~
  4. if ($pwd -eq $in) {write-host "密码正确"} else {write-host "密码错误"}
复制代码

TOP

六题,循环十秒倒计时
批处理
  1. @echo off
  2. for /l %%a in (10 -1 1) do echo;%%a&ping 127.1 -n 2 >nul
复制代码
powershell
用get-help about_for获取for的帮助信息
  1. for ($i=10;$i -gt 0;$i-=1) {$i;ping 127.1 -n 2|out-null}
复制代码
()圆括号内用分号;分别隔开初始值;条件;循环方法
{}大括号内用分号;隔开命令语句
ping 127.1 >nul 不能用在powershell中,看不懂提示,不知为何,百度到可以用管道加out-null。
我相信powershell应该有停顿一秒的命令、方法,只是我暂时没找到。

TOP

  1. for /f  "tokens=1,3,5 delims= "
复制代码
像这样挑选出第1,3,5列内容的用法,不知道powershell中有没有
一时想不到关键字去描述搜索
望路过大佬解惑

TOP

本帖最后由 for_flr 于 2021-11-30 11:05 编辑

七题,随机显示星期几
周一 周二 周三 周四 周五 周六 周日
利用随机数随机显示一天
批处理:
  1. @echo off
  2. ::作者bbcc的代码
  3. set "code=周一 周二 周三 周四 周五 周六 周日"
  4. :main
  5. set /a strRan=%random%%%7+1
  6. for /f "tokens=%strRan% delims=, " %%a in ("%code%") do (echo %%a)
  7. pause>nul
  8. goto :main
复制代码
  1. @echo off
  2. ::作者lhjoanna的代码
  3. set "str=一二三四五六日"
  4. set /a num=%random%%%7
  5. call echo 星期%%str:~%num%,1%%
  6. pause>nul
复制代码
powershell只能说666
  1. get-random -input "周一","周二","周三","周四","周五","周六","周日"
复制代码
get-random太好用了
  1. get-random -min 1 -max 8 #产生1到7的随机数,数字可指定负数或小数
复制代码
大于等于最小值,小于最大值】
  1. get-random -input 1,2,3,4,5,6,7
  2. #从-input后添加的集合中随机产生一个,也可以加 -count参数产生指定数量个。
复制代码
  1. get-childitem|get-random -count 2
  2. #可以加管道,dir结果中随机挑选2个显示出来。
复制代码

TOP

八题,建立1到10的文件夹,然后删除它们。
cmd
  1. for /l %%a in (1 1 10) do md %%a
复制代码
powershell中
new-item -name abc.txt -type file -value "hello" #new-item建立项,-name文件名,-value文件内容
new-item -name def -type directory #-type指定类型为文件或者文件夹。
  1. for ($i=1;$i -le 10;$i+=1){new-item -name $i -type directory} #建立1-10文件夹
复制代码
  1. get-childitem|?{$_.psiscontainer}|remove-item #删除目录下的文件夹
复制代码
暂时觉得批处理中,dir/b ,dir /s /a-d 等参数组合,比powershell更好用。
比如只显示当前目录下的文件夹
用$host看到我的ps版本为2.0,需要用
  1. get-childitem|?{$_.psiscontainer}    或者   get_childitem -exclude *.*
复制代码

TOP

本帖最后由 for_flr 于 2021-11-26 13:52 编辑

第九题,给txt中文本内容添加汉字行号(不超过10行)

十年生死两茫茫
不思量,自难忘
千里孤坟,无处话凄凉
纵使相逢应不识,尘满面,鬓如霜
夜来幽梦忽还乡
小轩窗,正梳妆
相顾无言,惟有泪千行
料得年年肠断处,明月夜,短松冈
  1. 一#十年生死两茫茫
  2. 二#不思量,自难忘
  3. 三#千里孤坟,无处话凄凉
  4. 四#纵使相逢应不识,尘满面,鬓如霜
  5. 五#夜来幽梦忽还乡
  6. 六#小轩窗,正梳妆
  7. 七#相顾无言,惟有泪千行
  8. 八#料得年年肠断处,明月夜,短松冈
复制代码
——————————————————
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. set s=一二三四五六七八
  4. set n=0
  5. for /f "delims=" %%a in (a.txt) do (
  6. call echo;%%s:~!n!,1%%#%%a
  7. set/a n+=1
  8. )
  9. pause>nul
复制代码
此题目好像有点难,先学习一下。

TOP

本帖最后由 for_flr 于 2021-11-29 14:18 编辑

powershell解题思路跟上面bat是一样的,唉,感觉走错胡同巷子了。
用get-content获取文本内容。
  1. $n=0
  2. $str="一二三四五六七八"
  3. foreach ($line in get-content a.txt){write-host $str.substring($n,1)"#"$line;$n=$n+1}
复制代码
#get-content a.txt|foreach{write-host $str.substring($n,1)"#"$_;$n++}  #等同于上一句
  1. (get-content a.txt).count    #获取a.txt文本行数。
  2. (get-content a.txt)[0,3]    #获取第1和第4行,因为数组下标从0开始计数,可用负数表示倒数计数。
  3. (get-content a.txt)[0..3]    #获取第1到第4行,..两个点表示范围操作符。
  4. get-content a.txt -totalcount 4    #获取前4行,据说无需完全读取文本,某些情境可提高效率。
复制代码

TOP

先列出接下来的几道题,有时间依次琢磨(题目挑选自本论坛批处理新手练功区)
10,获取当前目录路径
11,判断目录或文件是否存在
12,把文本的首行和尾行相拼接
13,过滤掉重复的行,然后保存到另一个文本文件
14,输入两个字母,显示它们之间的所有字母
15,字符串中的大小写互换
16,计算字符串长度
17,检查《千字文》是否有重复字
18,在控制台输出闪电图形

TOP

第十,没啥好说的,用get-location,赋值到变量$a=get-location。

十一,批处理的if exist,powershell中有test-path,test-path还支持通配符
  1. if (test-path .\*.mp3){write-host "当前目录有MP3文件"}else{write-host "无"}
复制代码
12,把文本首行和尾行相拼接。
批处理1
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /f "delims= " %%a in (a.txt) do (set/a num+=1&set !num!=%%a)
  4. ::对每一行依次赋值到数字序列
  5. echo !1!!%num%!
复制代码
批处理2
  1. @echo off
  2. set /p a=<a.txt
  3. ::获取首行
  4. for /f "delims=" %%i in (a.txt) do set b=%%i
  5. ::依次将行内容赋值到变量b,直到最后一行。
  6. echo %a%%b%
  7. pause>nul
复制代码
powershell
(get-content a.txt)[0,-1]  #文本内容视为数组,0是第一行,-1是最后一行。
  1. (get-content a.txt)[0]+(get-content a.txt)[-1] #用+连接第一行和最后一行。
复制代码

TOP

13,过滤掉重复的行,然后保存到另一个文本文件。假设有1.txt内容如下:
  1. 锄禾日当午
  2. 汗滴禾下土
  3. 锄禾日当午
  4. 锄禾日当午
  5. 谁知盘中餐
  6. 粒粒皆辛苦
  7. 白日依山尽
  8. 白日依山尽
  9. 白日依山尽
  10. 黄河入海流
  11. 粒粒皆辛苦
  12. 欲穷千里目
  13. 更上一层楼
  14. 更上一层楼
复制代码
批处理版:
  1. @echo off
  2. for /f "delims=" %%i in (1.txt) do (
  3.     if not defined %%i set %%i=1&echo;%%i>>2.txt
  4. )  
  5. pause
复制代码
powershell中有select-object,选择一个对象或一组对象的指定属性。它还可以从对象的数组中选择唯一对象,也可以从对象数组的开头或末尾选择指定个数的对象。
  1. get-content 1.txt|select-object -unique >2.txt
  2. # -unique ,从字符数组中选择唯一字符,即去除重复
复制代码
get-process | sort-object -property WS | select-object -Last 5
#此命令显示占用内存最多的五个进程。Sort-Object 用于按内存(工作集)使用量对进程排序,Select-Object 用于只选择所得到的对象数组的最后五个成员。

TOP

返回列表