我有一个包含两列文字的文件。使用批处理文件,我想提取第二列文本并获取字符串长度,然后将字符串长度和字符串文本写入输出文件。挑战我的步骤是确定具有特殊字符的字符串长度。例如,输入文件如下所示:
escitalopram CN(C)CCC[C@@]1(C2=C(CO1)C=C(C=C2)C#N)C3=CC=C(C=C3)F ibuprofen CC(C)CC1=CC=C(C=C1)C(C)C(=O)O keflex CC1=C(N2[C@@H]([C@@H](C2=O)NC(=O)[C@@H](C3=CC=CC=C3)N)SC1)C(=O)O aspirin CC(=O)OC1=CC=CC=C1C(=O)O linoleic_acid CCCCC/C=C\C/C=C\CCCCCCCC(=O)O
我可以使用批处理命令行和参数%1读取提取两个标记的文件。我已经尝试了一些我在讨论组中找到的子程序,但我无法让它们工作。 “=”符号和其他特殊字符可能会导致问题。我正在寻找一个可以生成输出文件的解决方案。忽略“@”,“/”和“\”符号:
escitalopram 49 ibuprofen 29 keflex 58 aspirin 24 linoleic_acid 25
到目前为止我的程序看起来像:
@echo off
setLocal EnableDelayedExpansion enableextensions
set arg1=%1
FOR /F "tokens=1,2 delims= " %%r IN (%1) DO (
set teststring="%%s"
echo "Passing " %%s
call :GetStrLength %%s
echo.%%s
goto :EOF
)
::========================
:GetStrLength
setlocal enableextensions
set s=%1
echo " counting.... " %1
:: Get the length of the quoted string assuming a max of 255
set charCount=0
for /l %%c in (0,1,255) do (
set si=!s:~%%c!
if defined si set /a charCount+=1)
if %charCount% EQU 256 set charCount=0
echo The length of "%s%" is %charCount% characters
endlocal & goto :EOF
任何帮助都将不胜感激。
答案 0 :(得分:2)
您可以使用strlen函数,但应使用byre而不是byval参数。
此函数可以处理任何字符串,它总是需要13个循环来确定长度 由于批处理中的变量可以包含不超过8191个字符,这就足够了。
echo off
set "myString=Any content"
call :strlen result myString
echo %result%
exit /b
:strlen <resultVar> <stringVar>
(
setlocal EnableDelayedExpansion
set "s=!%~2!#"
set "len=0"
for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
if "!s:~%%P,1!" NEQ "" (
set /a "len+=%%P"
set "s=!s:~%%P!"
)
)
)
(
endlocal
set "%~1=%len%"
exit /b
)
答案 1 :(得分:1)
=
导致问题,因为它没有引用,批处理解析器将=
视为标记分隔符。当您将包含=
的不带引号的字符串作为参数传递时,每个=
的字符串都会被分解为多个参数。应该可以通过添加一些策略性放置的引号来修复代码,以及使用~
参数扩展修饰符来根据需要删除封闭引号。这不是一般解决方案,但它应该适用于您的情况,因为我认为SMILES字符串不包含"
字符。请注意,包含引号的带引号的字符串将包含实际上未引用的字符串的某些部分。
这是您的代码已修复。我删除了一些不必要的代码和一些诊断消息。
@echo off
setlocal
FOR /F "tokens=1,2 delims= " %%r IN (%1) DO (
echo Passing "%%s"
call :GetStrLength "%%s"
goto :EOF
)
::========================
:GetStrLength
setlocal enableDelayedExpansion
set "s=%~1"
echo counting.... %1
:: Get the length of the quoted string assuming a max of 255
set charCount=0
for /l %%c in (0,1,255) do (
set si=!s:~%%c!
if defined si set /a charCount+=1
)
if %charCount% EQU 256 set charCount=0
echo The length of "%s%" is %charCount% characters
endlocal & goto :EOF
下面是一个完全有效的脚本,它在删除立体化学字符后计算每个SMILES字符串的长度。 (我很好奇为什么你想要这个价值)。它在jeb的答案中使用了非常快速的strlen函数的修正版本。我将USEBACKQ选项添加到初始FOR / F循环中,以防用户传递包含空格的带引号的文件名。
@echo off
setlocal enableDelayedExpansion
for /f "usebackq tokens=1,2 delims= " %%A IN (%1) do (
set "SMILES=%%B"
for %%C in (@ / \) do set "SMILES=!SMILES:%%C=!"
call :strlen len SMILES
echo %%A !len!
)
exit /b
:strlen <resultVar> <stringVar>
setlocal enableDelayedExpansion
set "s=!%~2!#"
set "len=0"
for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
if "!s:~%%P,1!" NEQ "" (
set /a "len+=%%P"
set "s=!s:~%%P!"
)
)
endlocal&set "%~1=%len%"
exit /b
答案 2 :(得分:0)
要获得字符串的长度,我发现following method非常有效。
@echo off
setLocal EnableDelayedExpansion
set s=%*
set length=0
:count
if defined s (
if "!s:~0,1!" NEQ "@" if "!s:~0,1!" NEQ "/" if "!s:~0,1!" NEQ "\" set /A length += 1
set "s=%s:~1%"
goto count
)
echo %length%
答案 3 :(得分:0)
@ECHO OFF
SETLOCAL
FOR /f "tokens=1*delims= " %%a IN (q21817684.txt) DO (
SET /a count=0
SET "chemical=%%a"
SET "formula=%%b"
CALL :report
)
GOTO :EOF
:report
SET "formula=%formula:@=%"
SET "formula=%formula:\=%"
SET "formula=%formula:/=%"
:reportl
IF DEFINED formula (
SET "formula=%formula:~1%"
SET /a count +=1
GOTO reportl
)
ECHO %chemical% %count%
GOTO :eof
我使用名为q21817684.txt
的文件进行测试。 Yor数据在keflex和阿司匹林的公式之后有一个尾随空格。我删除了我的测试,但添加了
SET "formula=%formula: =%"
显然应该是等效的。