我有一个txt文件,其中包含一些动物和水果的名称。 * 包含水果,# 包含动物。就像下面这样:-
* apple
# cat
* banana
# dog
* mango
# lion
* graps
我想对列表进行排序并像下面给出的表格一样编写:-
* apple # cat
* banana # dog
* mango # lion
我为此使用了
for
循环:
for /f "useback eol=* tokens=1-5 delims= " %%a in ("my text.txt") do (
for /f "useback eol=# tokens=1-5 delims= " %%c in ("my text.txt") do (
Echo %%a %%b
))
但它重复了。
请注意,
tokens
是单行的一部分。对于第一行,Token1=*
,token2=apple
,token3到5没有定义。每一行都一样。对于您的示例, tokeins=1,2
就可以了,但我决定使用 1,*
来考虑名称由两个(或更多)单词组成的动物或水果(例如 dragon fly
)
for /f "usebackq tokens=1,*" %%a in ("my text.txt") do (
if "%%a" == "*" (
<nul set /p "=%%a %%b "
) else (
echo %%a %%b
)
)
echo\
这使用了一种特殊的技巧来编写没有换行的字符串,以防该行以
*
<nul set /p "=string"
)
当然,这取决于源文本文件中交替的
*
和 #
行。
这可以使用以下方法在
cmd
或 batch-file
中完成。如果您使用的是受支持的 Windows 系统,则可以使用 PowerShell。
此代码将整个文件内容放入内存,然后将其拆分为
*
字符上的数组。第一个空数组元素将被跳过。然后,NewLine
和*
行之间的#
被替换为一些空格字符。
powershell.exe -NoLogo -NoProfile -Command ^
"(Get-Content -Path '.\fruit-animal.txt' -Raw) -split '\*' | Select-Object -Skip 1 | %{ '* ' + $_ -replace [Environment]::NewLine, ' '}"
这是数据文件和示例执行。
C:>TYPE .\fruit-animal.txt
* apple
# cat
* banana
# dog
* mango
# lion
* graps
C:>powershell.exe -NoLogo -NoProfile -Command ^
More? "(Get-Content -Path '.\fruit-animal.txt' -Raw) -split '\*' | Select-Object -Skip 1 | %{ $_ -replace [Environment]::NewLine, ' '}"
apple # cat
banana # dog
mango # lion
graps
这可能对你很有效,除非你有一个大文件。
如果使用 PowerShell Core http://github.com/PowerShell/Powershell(推荐),请更改为:
pwsh.exe -NoLogo -NoProfile -Command ^
"(Get-Content -Path '.\fruit-animal.txt' -Raw) -split '\*' | Select-Object -Skip 1 | %{ '* ' + $_ -replace [Environment]::NewLine, ' '}"
很难从您的具体情况中判断文本文件的内容和布局到底是什么,或者关于输出,您所说的表格到底是什么意思,以及这些表格中的空单元格是否可以接受。
在尝试尽可能保留您正在使用的想法时,并根据您提交的示例文本文件,假设不会有以
*
开头的连续两行,并使用水平制表符,如细胞分隔符,第 3 行Echo([TAB]%%G
,这是一个可能适合您目的的简单示例:
@For /F Delims^=^ EOL^= %%G In ('%SystemRoot%\System32\findstr.exe /BIL "* #"
"S:\ome\Directory\my text.txt" 2^>NUL') Do @(
For /F "EOL=* Delims=" %%H In ("%%G") Do @Echo( %%G
For /F "EOL=# Delims=" %%I In ("%%G") Do @Set /P "=%%G" 0<NUL)
@Echo(& Pause
示例输出 (已纠正拼写错误
graps
):
* apple # cat
* banana # dog
* mango # lion
* grape
如果您不想在生成的输出文件中包含
*
和 #
字符,即
apple cat
banana dog
mango lion
grape
然后稍微修改一下代码,第 3 行会有
Echo([TAB]%%I
:
@For /F Delims^=^ EOL^= %%G In ('%SystemRoot%\System32\findstr.exe /BIL "* #"
"S:\ome\Directory\my text.txt" 2^>NUL') Do @(
For /F "EOL=* Tokens=1,*" %%H In ("%%G") Do @Echo( %%I
For /F "EOL=# Tokens=1,*" %%J In ("%%G") Do @Set /P "=%%K" 0<NUL)
@Echo(& Pause
任务描述、示例输入和输出数据与发布的代码完全不匹配。所以很难理解任务到底是什么。
下面的第一个批处理文件代码用于从数据文件中读取所有非空行,并将每个非空奇数行与每个非空偶数行合并在一起,最后用包含合并行的临时文件替换源数据文件.
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "DataFile=Data.txt"
if not exist "%DataFile%" goto MissingFile
set "TempFile=%DataFile%.tmp"
set "LineOdd="
set "LineEven="
(
for /F usebackq^ delims^=^ eol^= %%I in ("%DataFile%") do (
if defined LineOdd (
set "LineEven=%%I"
setlocal EnableDelayedExpansion
echo(!LineOdd! !LineEven!
endlocal
set "LineOdd="
set "LineEven="
) else set "LineOdd=%%I"
)
if defined LineOdd (
setlocal EnableDelayedExpansion
echo(!LineOdd!
endlocal
set "LineOdd="
)
)>"%TempFile%"
if /I not "%~1" == "test" (move /Y "%TempFile%" "%DataFile%") else type %TempFile%"
del "%TempFile%"
exit /B
:MissingFile
echo ERROR: There is no file "%DataFile%" in "%CD%".
echo(
pause
endlocal
可以使用字符串
test
作为参数来运行此批处理文件,以仅输出最终结果而不是覆盖源数据文件。
文件
Data.txt
可能包含以下几行:
* apple
# cat
# dog
* banana
* mango
# lion
* grapes
* pear
* plum
# mouse
# canary
# hamster
* cherry
上面批处理文件的结果是:
* apple # cat
# dog * banana
* mango # lion
* grapes * pear
* plum # mouse
# canary # hamster
* cherry
下面的第二个批处理文件代码实际上查看行开头的标识符
*
和 #
以确定该行的其余部分是否应位于输出文件的左侧或右侧。此代码将忽略所有不以 *
和 #
开头的行。
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "DataFile=Data.txt"
if not exist "%DataFile%" goto MissingFile
set "TempFile=%DataFile%.tmp"
set "DataLeft="
set "DataRight="
(
for /F "usebackq tokens=1*" %%I in ("%DataFile%") do (
if "%%I" == "*" (
if not defined DataLeft (
set "DataLeft=%%J"
) else if defined DataRight (
setlocal EnableDelayedExpansion
echo(!DataLeft! !DataRight!
endlocal
set "DataLeft=%%J"
set "DataRight="
) else (
setlocal EnableDelayedExpansion
echo(!DataLeft!
endlocal
set "DataLeft=%%J"
)
) else if "%%I" == "#" (
if not defined DataRight (
set "DataRight=%%J"
) else if defined DataLeft (
setlocal EnableDelayedExpansion
echo(!DataLeft! !DataRight!
endlocal
set "DataRight=%%J"
set "DataLeft="
) else (
setlocal EnableDelayedExpansion
echo( !DataRight!
endlocal
set "DataRIGHT=%%J"
)
)
)
if defined DataLeft (
if defined DataRight (
setlocal EnableDelayedExpansion
echo(!DataLeft! !DataRight!
endlocal
set "DataLeft="
set "DataRight="
) else (
setlocal EnableDelayedExpansion
echo(!DataLeft!
endlocal
set "DataLeft=%%J"
)
)
if defined DataRight (
setlocal EnableDelayedExpansion
echo( !DataRight!
endlocal
set "DataRight="
)
)>"%TempFile%"
if /I not "%~1" == "test" (move /Y "%TempFile%" "%DataFile%") else type "%TempFile%"
del "%TempFile%"
exit /B
:MissingFile
echo ERROR: There is no file "%DataFile%" in "%CD%".
echo(
pause
endlocal
这个批处理文件也可以使用参数
test
执行,只输出最终结果,而不是覆盖源数据文件。
上面相同数据文件示例的输出是:
apple cat
banana dog
mango lion
grapes
pear
plum mouse
canary
cherry hamster
可以看到,左边是数据文件中标有
*
的水果,右边是标有#
的动物。
要了解所使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完整、仔细地阅读每个命令显示的帮助页面。
call /?
... 的解释 %~1
del /?
echo /?
endlocal /?
exit /?
for /?
goto /?
if /?
move /?
pause /?
set /?
setlocal /?
type /?