[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]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
复制代码

千字文,统计重复单字
  1. $txt=(gc qzw.txt).split()|?{$_ -ne ""}
  2. $dic=@{}
  3. foreach($w in $txt){
  4. for($i=0;$i -le 3;$i++){
  5. if (!$dic.containskey($w[$i])){
  6. $dic[$w[$i]]=1
  7. } else {
  8. $dic[$w[$i]]+=1
  9. }
  10. }
  11. }
  12. write-host "千字文中有以下重复字"
  13. $dic.getenumerator()|?{$_.value -gt 1}
  14. [console]::readkey()
复制代码

TOP

小结2:
回顾一楼第一题到30楼十九题。补充更正一些东西。
产生01-20递增序列
  1. foreach($a in 101..120){($a|out-string).remove(0,1)}
  2. 101..120|%{($_|out string).remove(0,1)} #之前没了解对象,错误理解了.remove()
  3. 1..20|%{"{0:d2}" -f $_}
复制代码
范围操作符..,表示连续数字。如-1..-9生成-1到-9的数组
格式化输出字符串-f,如下
  1. "{0,15}{1,15}{2,15}" -f 1,2,3
  2. "{0,15}{1,15}{2,15}" -f "hello","boy","!"
复制代码
固定字符长度,不足的补空格。{}大括号中,逗号前的数字表示-f后面所跟参数的下标。
{}大括号中,逗号后的数字表示字符占位长度
  1. ("{0,15}{1,15}{2,15}" -f 1,2,3).length  #用这两个可以加强印象
  2. ("{0,15}{1,15}{2,15}" -f "hello","boy","!").length
复制代码
  1. "{0:d8}" -f 3 #冒号后的d表示数字的补零,8表示8位
复制代码
冒号后还可以换f表示小数,p表示百分数,x表示16进制...

10秒倒计时
  1. foreach ($i in 10..1){$i;sleep -s 1}
复制代码
Measure-command{foreach ($i in 10..1){$i;sleep -s 1}}  #用measure看了下,挺精准。

类似for /f "delims= tokens=5"切割并挑选。
  1. "abc def 123 456 apple 123 45".split(" ")[4]
  2. ("abc-123-###-电源盒子-powershell" -split "-")[2,4]
复制代码
给小诗加汉字行号
  1. foreach($n in 0..7){"一二三四五六七八"[$n]+"#"+(gc a.txt)[$n]}
复制代码
建立1-10文件夹
  1. foreach($i in 1..10){md $i}
复制代码
  1. md (1..10)  #还能这样!
复制代码
关于这种格式用法[system.io.path]::getfilename()
::静态成员运算符,[]方括号中是类名。
类名::属性名     ,类名::方法名()  
.成员运算符
$对象.属性        ,$对象.方法()

千字文
  1. ((gc a.txt) -replace (" ","")|measure-object  -char).characters
复制代码
measure-command验证效率略高于原答案
  1. ((gc a.txt) -split(" ")|?{$_ -ne ""})[-1..-250] #逆序输出并去空行
复制代码

TOP

小结1:
有一定批处理基础,学习powershell的语法和各命令用法肯定是没有问题的。觉得难,其实主要是两个脚本思路完全不一样了。必须牢记powershell处理对象,了解各种对象本身具有哪些属性和方法,用语法组织这些属性方法解决问题。

TOP

练一道题,第19,把每行中等于8个字符的字符串提取出来,其他行过滤掉。
示例文本 a.txt
  1. 12345678 abc cde
  2. 批处理之家
  3. 一二三四五六七八  abcdefgh
  4. 新手练功区欢迎大家
复制代码
其实字符串长度题目重复了,这里主要是套用两个foreach循环,练一练:
  1. $file=1.txt
  2. get-content $file|foreach{
  3.     foreach ($s in $_.split()) {
  4.     if ($s.length -eq 8) {$s}
  5.     }
  6. }
复制代码

TOP

回复 28# 心远先生


    已改正,谢谢提醒。
另,借本楼贴出[system.io.path]的学习记录。
坛友提问:如何使用Powershell 将一个文件复制10份,文件名加后缀从1递增到10,如a.txt,复制出a1.txt,a2.txt到a10.txt
  1. $a="a.txt"
  2. for ($i=1;$i -le 10;$i++){copy $a (dir $a).name.insert(1,$i)}
复制代码
这样写不通用,搜索了一会儿,看到[system.io.path]::getxxx的用法,记录如下:
  1. $filename="test.mp3"
  2. $n=10
  3. $fn=[system.io.path]::getfilenamewithoutextension($filename)
  4. $fx=[system.io.path]::getextension($filename)
  5. for ($i=1;$i -le $n;$i++){copy-item $filename $fn$i$fx}
复制代码
  1. [system.io.path]::getfilename() #获取文件名
  2. [system.io.path]::getfilenamewithoutextension() #获取文件名,不含后缀
  3. [system.io.path]::getextension() #获取文件后缀名
  4. [system.io.path]::getfullpath() #获取全路径且带文件全名
  5. [system.io.path]::getdirectoryname() #获取文件父目录名   (括号里的文件名需要带绝对路径)
  6. [system.io.path]::getpathroot() #获取文件所在盘符        (括号里的文件名需要带绝对路径)
复制代码
不知道这种用法叫什么名字,不知道还有没有其他的,希望路过的大佬补充一下

TOP

回复 8# for_flr


    bathome写成hathome,新手看不懂容易误会,纠正下

TOP

本帖最后由 for_flr 于 2021-11-29 15:39 编辑

18,输出类似的闪电图形
  1. @echo off&setlocal enabledelayedexpansion
  2. for /l %%a in (1 1 11) do set "空格=!空格! "&set "星号=!星号!*"
  3. for /l %%a in (1 1 10) do echo !空格:~%%a!!空格:~%%a!!星号:~,%%a!
  4. for /l %%a in (10 -1 1) do echo !空格:~-%%a!!星号:~-%%a!
  5. pause
复制代码
powershell
  1. $a="*"
  2. for ($i=40;$i -ge 20;$i-=2){"{0,$i}" -f $a;$a=$a+"*"}
  3. for ($i=30;$i -ge 8;$i-=2){"{0,$i}" -f $a;$a=$a.remove(0,1)}
复制代码

TOP

第17,关于千字文的3个问题,
1,统计千字文数量,不含空格,共一千字。
  1. Get-Content 千字文.txt|foreach {$num+=($_.replace(" ","")).length}
  2. $num
  3. #去除每一行的空格后,累加文字长度
复制代码
坐等更效率的处理方式
2四字词语倒序输出
  1. get-content 千字文.txt|foreach {$new+=$_.split()}
  2. ($new)[-1..-$new.count]
  3. #将千字文逐行分成6个四字词语,累计存到变量new里,$new.count=588(含空行588行)
  4. #最后用数组的[-1..-588]形式,完成倒序输出
复制代码
视觉效果不理想,有空白行干扰
3,统计文中的重复字,暂无满意办法...

TOP

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

17,检查千字文是否有重复字,且统计千字文文字数量,且将四字词语逆序输出
http://www.bathome.net/thread-12590-1-2.html
批处理代码不贴了,都在帖子里。
(题目作者很鸡贼,在txt末尾加了两个空行,其中一个空行里有个空格键.)

TOP

16计算字符串长度
批处理
  1. @echo off
  2. set str=123ABC上中下
  3. :loop
  4. set /a a+=1
  5. set str=%str:~0,-1%
  6. if "%str%"=="" (echo %a%&pause>nul ) else goto loop
复制代码
powershell
  1. $str="123ABC上中下"
  2. $str.length
复制代码

TOP

回复 20# for_flr
  1. $s = 'abcdefghijklmnopqrstuvwxyz';
  2. $a = Read-Host '请输入两个字母';
  3. $s.Split($a)[1]
复制代码
  1. $a = read-host "请输入两个字母";
  2. [char[]](([int]$a[0]+1)..([int]$a[1]-1));
复制代码
1

评分人数

    • for_flr: 妙啊!我咋这么死板技术 + 1

TOP

本帖最后由 for_flr 于 2021-11-29 12:46 编辑

powershell
接触了foreach和split,字符串的.toupper()、.tolower()
那这题就太简单了
将字符串拆分成单子,逐字对比判断字符是大写还是小写,再转化
  1. $a="abcdABCD 123 XyZ"
  2. $a -split ""|foreach{if ($_ -ceq $_.tolower()){$na+=$_.toupper()}else{$na+=$_.tolower()}}
  3. $na
复制代码
powershell果然机具power!!
注: if 中的 eq代表等于,ceq代表等于且区分大小写

TOP

15题,字符串中大小写互换
批处理1
  1. @echo off
  2. set "letters= abcdefghijklmnopqrstuvwxyzZYXWVUTSRQPONMLKJIHGFEDCBA"
  3. for /l %%a in (1,1,26) do call set /a "_%%letters:~%%a,1%%=%%a"
  4. :input
  5. setlocal EnableDelayedExpansion
  6. echo 请输入:&set /p var=&if not defined var endlocal&goto:input
  7. :loop
  8. set char=!var:~%pi%,1!
  9. set /a sn=_!char! 2>nul||set sn=0
  10. if defined char (
  11.     if %sn% gtr 0 (
  12.         if "!char!"=="!letters:~%sn%,1!" (set str=!str!!letters:~-%sn%,1!) else (set str=!str!!letters:~%sn%,1!)
  13.     ) else (
  14.         set str=!str!!char!
  15.     )
  16.     set /a pi+=1
  17.     goto loop
  18. )
  19. echo=!str!
  20. pause&endlocal&goto input
复制代码
批处理2
  1. @echo off & setlocal enabledelayedexpansion
  2. (for %%a in (a_A b_B c_C d_D e_E f_F g_G h_H i_I j_J k_K l_L m_M n_N o_O p_P q_Q r_R s_S t_T u_U v_V w_W x_X y_Y z_Z A_a B_b C_c D_d E_e F_f G_g H_h I_i J_j K_k L_l M_m N_n O_o P_p Q_q R_r S_s T_t U_u V_v W_w X_x Y_y Z_z) do echo;%%a)>temp.txt
  3. :loop
  4. cls&echo;输入混杂大小写的字母串(不超过15位)&set /p var=
  5. for /l %%b in (0,1,15) do (
  6. set "zifu=!var:~%%b,1!"
  7. if "!zifu!"=="" pause>nul&goto loop
  8. for /f "tokens=2 delims=_" %%c in ('findstr /b "!zifu!" temp.txt') do set /p=%%c<nul
  9. )
  10. pause&goto loop
复制代码

TOP

本帖最后由 for_flr 于 2021-11-29 13:06 编辑

powershell
  1. $str="abcdefghijklmnopqrstuvwxyz"
  2. $input=read-host "请输入两个字母"
  3. $sp=$input.substring(0,1)+"|"+$input.substring(1,1)
  4. ($str -split "$sp")[1]
复制代码
#将输入的字母视作分隔符,把字母表分割成3段,显示第二段。
-split的分割用法:
"张三-23-男-法外狂徒" -split "-"
我好傻,第三行应该用.insert()或者.chars()

——————————
根据24楼WHY前辈指点,可以简化为
  1. $s = 'abcdefghijklmnopqrstuvwxyz';
  2. $a = Read-Host '请输入两个字母';
  3. $s.Split($a)[1]
复制代码
而本人原答案中,
只知道-split 如果指定多个分隔符,应该用|符号隔开,如: "a|b"
所以用$sp=$input.substring(0,1)+"|"+$input.substring(1,1) 构建 a|b,徒增笑尔。

TOP

返回列表