Board logo

标题: [文本处理] [已解决]批处理find命令的输出能不能直接用set定义成/赋值给变量? [打印本页]

作者: guaiwu    时间: 2011-10-17 20:30     标题: [已解决]批处理find命令的输出能不能直接用set定义成/赋值给变量?

本帖最后由 pcl_test 于 2016-7-16 15:05 编辑

我想在600050.txt文件中筛选出字符串,想利用find显示出来的set定义在一个变量上。
我知道for可以做到
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. (sort 600050.txt | find  "☆曾用名")>%temp%/1.txt
  4. for /f "delims=" %%i in (%temp%/1.txt) do set a=%%i
  5. echo !a:~0,-5!
复制代码
如果不用for命令能不能直接set定义
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. sort 600050.txt | find  "☆曾用名" |set /p a=
  4. echo  !a:~0,-5!
复制代码
上面这段代码有问题,小弟实在是想不出来了。    想求各位帮忙想想。
作者: powerbat    时间: 2011-10-17 20:55

不能这样滴
作者: guaiwu    时间: 2011-10-17 21:06

回复 2# powerbat


我想有个解释。   或许用某种方法可以,但除了for
作者: powerbat    时间: 2011-10-17 21:24

Windows下只有这种方法,不需要解释。
Linux下就没有这种方法了,是其他方式,比如var1=`dir`
作者: guaiwu    时间: 2011-10-17 21:49

回复 4# powerbat

不是吧!  我再等等答案吧。
作者: awk    时间: 2011-10-17 22:17

  1. @echo off
  2. setlocal enabledelayedexpansion
  3. (sort 600050.txt | find  "☆曾用名")>%temp%/1.txt
  4. set /p a=<%temp%/1.txt
  5. echo !a:~0,-5!
复制代码

作者: guaiwu    时间: 2011-10-18 00:10

回复 6# awk


非常感谢。  又多了一个参考,我认为能不能实现把代码一行就解决了。
不行就算了    我也觉得太勉强了。
作者: FOR    时间: 2011-10-18 00:44

除了从文件获取就只有for了,不明白你那个 sort 有什么用
  1. @echo off
  2. for /f "delims=" %%i in ('find "☆曾用名" 600050.txt') do set a=%%i
  3. pause
复制代码

作者: powerbat    时间: 2011-10-18 14:25

用临时文件?得不偿失。
用sort可能是有多个结果,想进行排序。
作者: CrLf    时间: 2011-10-18 15:09

回复 9# powerbat

那要看楼主的需求是什么了,如果速度优先,使用临时文件无疑更合适。而且 for /f 其实也不绿色,直接解析命令输出的代价是要开启额外的 cmd 进程,也就是执行了一个 cmd /c。
作者: CrLf    时间: 2011-10-18 15:14

至于 echo something|set /p str= 的这种做法至今未见成功的实例,原因不明。
作者: powerbat    时间: 2011-10-18 15:16

用临时文件速度就很快吗?创建进程与写磁盘,哪种效率高?我没有测试过。
有些情况下是创建不了临时文件的,所以直接解析命令输出更通用一些。
作者: powerbat    时间: 2011-10-18 15:25

回复 11# CrLf


verybat关闭前一段时间我在zqz0012005版主的一个讨论管道机制的帖子中看到过:
  1. echo hello|set /p var=
  2. 其实就是
  3. echo hello|cmd /S /D /c"set /p var="
  4. echo hello|cmd /v /c "set /p var=&echo !var!"
复制代码
变量var是属于子进程的,外面的父进程cmd访问不到。(而且子进程很快退出)
作者: guaiwu    时间: 2011-10-18 19:25

本帖最后由 guaiwu 于 2011-10-18 19:30 编辑

回复 8# FOR


正如more一样  只是想将查找到的字符串输出,用find筛选一遍,最后将字符转存进a里面。   
就像楼下有人说的
  1. echo xinwenjian | set /p a=
复制代码
一样。想找个理由。


很感谢参与了。
作者: guaiwu    时间: 2011-10-18 19:39

回复 13# powerbat


感谢回复了
根据所提供的的
echo hello|set /p var=
其实就是
echo hello|cmd /S /D /c"set /p var="

echo hello|cmd /v /c "set /p var=&echo !var



我应用到题目里去
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. sort 600050.txt | find  "☆曾用名" |cmd /v /c "set /p var="
  4. echo %var%
  5. pause
复制代码
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. type 600050.txt | find  "☆曾用名" | cmd /v /c "set /p var="&echo !var!
  4. pause
复制代码
已经将sort改成type输出文本内容。  可结果还是一样。
作者: guaiwu    时间: 2011-10-18 19:40

回复 10# CrLf


如目前不考虑效率,只求能在一行完成此命令呢。

呵呵!劳心了。
作者: awk    时间: 2011-10-18 19:46

回复 16# guaiwu


这样算一行吗?
  1. @echo off & setlocal enabledelayedexpansion & (sort 600050.txt | find  "☆曾用名")>%temp%/1.txt & set /p a=<%temp%/1.txt & echo !a:~0,-5!
复制代码

作者: CrLf    时间: 2011-10-18 21:08

回复 13# powerbat


    精彩!我倒是知道管道前后存在内部命令或语块时会开启新的 cmd 环境,但是忽略了这个 cmd 是子进程,它继承但并不与父进程共享变量环境。
   如此一来,这个谜题终于有了最合理的解释...又谈到 verybat,照例干号一下,为什么我学批不早两年啊~
作者: CrLf    时间: 2011-10-18 21:14

回复 16# guaiwu


    不是已经有人给了吗?像 powerbat 说的那样在子进程中赋值、在子进程中调用就可以呀:
  1. find "☆曾用名" 600050.txt|cmd /v /c "set /p var=&echo !var!"
复制代码
或者 8 楼 for 的代码也可以啊,使用后有何处不符合要求呢?
   不过还是建议用 8 楼方案,毕竟 13 楼的技巧虽深刻,但此时并不合适。
作者: guaiwu    时间: 2011-10-18 22:30

回复 19# CrLf


按照你的代码,省略sort、more、type等命令那个去执行  小弟琢磨觉得有两个问题

第一,如果只用find "☆曾用名" 600050.txt 命令会在多一个不需要的 ---------- 11.TXTt这一段
第二,即使用了findstr命令,---------- 11.TXT解决了  但是
  1. setlocal enabledelayedexpansoin
  2. find "☆曾用名" 600050.txt | cmd /v /c "set /p var="&echo !var!
  3. pause
复制代码
一样出错。
echo 显示不了了!var!
作者: CrLf    时间: 2011-10-18 23:21

本帖最后由 CrLf 于 2011-10-18 23:23 编辑

回复 20# guaiwu


    那是因为你的 set /p 与 echo !var! 不在同一个进程中,先执行 【find "☆曾用名" 600050.txt | cmd /v /c "set /p var="】成功赋值,然后退出子进程后才执行 echo !var!,而此时已经是在父进程中了,子进程的变量环境随着子进程的结束已经随之销毁,当然取不到。而且你开了变量延迟又没有把 !var! 转义,要么先不要开变量延迟,要么就转义 !var!,修改如下:
  1. find "☆曾用名" 600050.txt | cmd /v /c "set /p var=&echo !var!"
  2. pause
复制代码
  1. setlocal enabledelayedexpansoin
  2. find "☆曾用名" 600050.txt | cmd /v /c "set /p var=&echo ^!var^!"
  3. pause
复制代码

作者: wc726842270    时间: 2011-10-19 00:40

13L的代码却实很精彩,
不过说实话,感觉进程这个词还是大了些。引号用的非常到位(给力)
作者: guaiwu    时间: 2011-10-19 16:48

回复 21# CrLf


如图显示  加上了延迟变量。还是不能显示!var!变量。
作者: Batcher    时间: 2011-10-19 17:12

回复 22# wc726842270


为什么说进程这个词还是大了些?




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2