标题: [文本处理] [分享]批处理只保留字符串里面的数字 [打印本页]
作者: Batcher 时间: 2023-1-7 21:39 标题: [分享]批处理只保留字符串里面的数字
【问题描述】
怎么提取字符串里面的数字,删除其它字符,
比如:123Bat456Home789论坛
结果:123456789
作者: Batcher 时间: 2023-1-7 21:39
【解决方案】
test_1.bat
这个代码有问题,请参考6楼的方法。- @echo off
- setlocal enabledelayedexpansion
- set "StrOld=123Bat456Home789论坛"
- set "StrTmp=%StrOld%"
- for /l %%i in (0 1 9) do (
- set "StrTmp=!StrTmp:%%i= !"
- )
- set "StrNew=%StrOld%"
- for %%i in (!StrTmp!) do (
- set StrNew=!StrNew:%%i=!
- )
- echo,!StrNew!
- pause
复制代码
作者: Batcher 时间: 2023-1-7 21:45
test_2.bat- @echo off
- setlocal enabledelayedexpansion
- set "str=123Bat456Home789论坛"
- set "num="
- :Loop
- set "char=%str:~0,1%"
- if %char% geq 0 (
- if %char% leq 9 (
- set "num=!num!%char%"
- )
- )
- set str=%str:~1%
- if "%str%" neq "" (
- goto :Loop
- )
- echo,%num%
- pause
复制代码
作者: Batcher 时间: 2023-1-7 21:53
test_3.bat- @echo off
- set "StrOld=123Bat456Home789论坛"
- for /f "delims=" %%i in ('powershell "'%StrOld%' -replace '[^\d]*',''"') do (
- set "StrNew=%%i"
- )
- echo,%StrNew%
- pause
复制代码
作者: hfxiang 时间: 2023-1-8 08:57
来个第3方工具gawk( http://bcn.bathome.net/tool/4.1.0/gawk.exe )的实现方法- echo;123Bat456Home789 论坛|gawk -vOFS="" -F"[^0-9]+" "$1=$1"
复制代码
作者: qixiaobin0715 时间: 2023-1-8 09:14
本帖最后由 qixiaobin0715 于 2023-1-8 10:29 编辑
回复 2# Batcher
2楼代码有bug。如果对于数字分隔的非数字字段来说,存在前面字段包含于后面的字段,就会出现问题,比如:- set "StrOld=123Bat456BatHome789论坛"
复制代码
前面的Bat字段包含于后面的BatHome字段,处理后的结果为:复制代码
这样应当可以:- @echo off
- setlocal enabledelayedexpansion
- set "StrOld=123Bat456BatHome789论坛"
- for /l %%i in (0 1 9) do (
- set "StrOld=!StrOld:%%i= %%i !"
- )
- for %%i in (!StrOld!) do (
- if %%i geq 0 (
- if %%i leq 9 (
- set StrNew=!StrNew!%%i
- )
- )
- )
- echo,!StrNew!
- pause
复制代码
作者: Batcher 时间: 2023-1-8 11:49
回复 5# hfxiang
再来个sed- echo 123Bat456Home789论坛 | sed "s/[^0-9]//g"
复制代码
作者: 77七 时间: 2024-6-24 10:23
回复 5# hfxiang
大佬,请教下,我把命令写到for里面,为什么结果之前多了一个数字 1 呢?- @echo off
- cd.>a1.txt
- for /f "delims=" %%i in ('dir /b /a-d *.txt') do (
- for /f "delims=" %%j in ('echo;%%~ni^|gawk -vOFS^="" -F"[^0-9]+" "$1^=$1"') do (
- echo [%%j]
- )
- )
- pause
复制代码
作者: ShowCode 时间: 2024-6-24 11:21
回复 8# 77七 - @echo off
- for /f "delims=" %%i in ('dir /b /a-d *.txt') do (
- for /f "delims=" %%j in ('echo %%~ni ^| gawk -v OFS^="" -F "[^0-9]+" "$1=$1"') do (
- echo [%%j]
- )
- )
复制代码
C:\Test>dir /b *.txt
123Bat456Home789.txt
C:\Test>1.bat
[123456789]
C:\Test>gawk --version
GNU Awk 5.1.0, API: 3.0
作者: 77七 时间: 2024-6-24 11:32
本帖最后由 77七 于 2024-6-24 11:40 编辑
回复 9# ShowCode
感谢大佬帮助!我测试了以字母开头的文件名,结果为空,比如 a1.txt。用5楼代码 测试 字母开头的字符串,结果同样为空。
作者: aloha20200628 时间: 2024-6-24 17:24
本帖最后由 aloha20200628 于 2024-6-24 17:36 编辑
借8楼旧帖新续,也给几个版本仅供参考,示例题型》提取并链接当前目录中全部文本文件名包含的数值字段
一。采用纯P递归方法
二。调用jscript正则替换方法
三。调用sed.exe正则替换方法
四。调用powershell正则替换方法
- @set @x=1 /* &@echo off &setlocal
- for %%F in (*.txt) do (
- set "_F=" &(call :get#n "%%~nF")
- for /f %%a in (' cscript /nologo /e:jscript "%~f0" "%%~nF" ') do echo,%%a
- for /f %%a in (' echo,"%%~nF"^|sed "s/[^0-9]//g" ') do echo,%%a
- for /f %%a in (' powershell " '%%~nF' -replace '[^\d]' " ') do echo,%%a
- )
- endlocal&pause&exit/b
- :get#n
- if "%~1"=="" echo,%_F%&exit/b
- set s=%~1
- set c=%s:~,1%
- if "%c%" geq "0" if "%c%" leq "9" set _F=%_F%%c%
- call :get#n "%s:~1%"
- exit/b
- */
- v=WSH.arguments, WSH.echo(v(0).replace(/[^\d]/g,'')), WSH.quit();
复制代码
作者: WHY 时间: 2024-6-24 18:17
本帖最后由 WHY 于 2024-6-24 23:31 编辑
回复 10# 77七
echo;a1|gawk -vOFS="" -F"[^0-9]+" "$1=$1"
这个时候 $1 值为空,可能 gawk 认为 "$1=$1" 赋值后条件不成立,所以没有输出。- for /f %%i in ('echo;a123Bat456Home789 论坛^|gawk "{gsub(/[^0-9]+/, \"\")}1"') do echo [%%i]
复制代码
或者- for /f %%i in ('echo;a123Bat456Home789 论坛^|gawk -vOFS^="" -F"[^0-9]+" "NF=NF"') do echo [%%i]
复制代码
试试。
作者: 77七 时间: 2024-6-24 20:18
回复 11# aloha20200628
感谢大佬分享!正则替换很强大。
作者: 77七 时间: 2024-6-24 20:27
回复 12# WHY
感谢大佬分享!之前没有结果,我还以为是转义出现了问题,把引号内的等号也转义了,结果却多了个数字1。5楼的gawk代码我看不懂,尤其是$1,经过您指点,我大概理解是 批处理中的 第一列的意思,我尝试添加了第二列,结果居然是对的。
- echo;a1b2c3|gawk -vOFS="" -F"[^0-9]+" "$1=$1;$2=$2"
复制代码
作者: ShowCode 时间: 2024-6-24 20:32
回复 10# 77七 - @echo off
- for /f "delims=" %%i in ('dir /b /a-d *.txt') do (
- for /f "delims=" %%j in ('echo %%~ni ^| gawk -v OFS^="" -F "[^0-9]+" "NF+=0"') do (
- echo [%%j]
- )
- )
复制代码
作者: buyiyang 时间: 2024-6-24 20:39
回复 10# 77七
$1^=$1是$1=$1^$1,$1是空值,在数值计算中被视为0,$1的0次方为1。
$1=$1是赋值语句,赋值语句的真假通过赋值后的值判断,$1为空即假, 不执行输出。
作者: 77七 时间: 2024-6-24 20:39
回复 15# ShowCode
感谢大佬分享!测试代码结果正确。
作者: 77七 时间: 2024-6-24 21:36
回复 16# buyiyang
感谢大佬分享!我现在明白了为什么多了个数字1了。我自己尝试了一会,对$0,$1-n有了初步的了解,如 如果$2不为空,$1=$2,会多出第二列。
作者: aloha20200628 时间: 2024-6-25 12:23
用11楼的4种方法作了用时测试(分别获取同一组约50个文件名的数值字段总和最终定向到各自的结果文件),分享一下结果数据如下...
sed方法》用时0.37s(1.0)
call方法》用时0.76s(2.1)
jscript方法》用时0.95s(2.6)
powershell方法》用时6.92s(18.7)
除了纯P的call方法之外,其余三种外部调用方法均经历两层循环体,虽然powershell功能丰富且代码轻量化,但用时最长
作者: WHY 时间: 2024-6-25 20:14
本帖最后由 WHY 于 2024-7-2 00:25 编辑
- dir /b /a-d *.txt | sed -r "/[0-9]/!d; s/[^0-9]+//g"
复制代码
- dir /b /a-d *.txt | gawk "/[0-9]/{gsub(/[^0-9]+/, \"\");print}"
复制代码
- PowerShell "(dir *[0-9]*.txt -File).BaseName -replace '\D+'"
复制代码
- @if(0)==(0) echo off
- dir /b /a-d *.txt | cscript //nologo //e:jscript "%~f0"
- pause & exit
- @end
-
- while (!WSH.StdIn.AtEndOfStream) {
- var s = WSH.StdIn.Readline().replace(/\D+/g, '');
- if (/./.test(s)) WSH.Echo(s);
- }
复制代码
假设文件名不超过256个字符。事实上,在默认情况下,Windows系统中的路径长度被限制在256个字符以内。
0x!s:~15,1! 应该是16- @echo off
- for /L %%i in (0 1 9) do set _%%i=1
- for /f "delims=" %%i in ('dir /b /a-d *.txt ^| findstr "[0-9]"') do (
- set "name=%%~ni"
- setlocal enabledelayedexpansion
- set "s=!name!"
- for %%j in (128 64 32 16) do (
- if "!s:~%%j!" NEQ "" (
- set /a Len+=%%j
- set "s=!s:~%%j!"
- )
- )
- set "s=!s!FEDCBA9876543210"
- set /a Len+=0x!s:~16,1!
- for /L %%j in (0 1 !Len!) do (
- set "s1=!name:~%%j,1!"
- if defined _!s1! (
- set "newName=!newName!!s1!"
- )
- )
- echo;!newName!
- endlocal
- )
- pause
复制代码
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |