2014-03-12 53 views
2

我需要一个Windows Cli中的等效方法来做我能够在Linux/UNIX中通过管道显示唯一值的功能。等效于“sort -u”的DOS命令

我不认为有这样一个命令,从我能收集到的东西,所以有另一种方式来做到这一点?

我必须acheieve是列出多个目录中的文件(无论它们是否存在以及我目前使用dir)。脚本(用于请求应用程序)工作的方式使用多个来源构建目录列表,随后根据平台是Windows还是UNIX来执行命令,但这里的危险是列表中可能存在重复的目录,并且这会在另一端扭曲结果。

处理这个问题的最简单方法是在源代码处执行,即运行原始命令。所以在Linux中,命令结构或多或少:

find [dir] [dir] [dir] | grep file_name | sort -u 

做同样在Windows中显然是更加困难考虑到:

  • 它必须是原生只读命令/脚本字符串你将一个标准的cmd.exe提示符下使用
  • 我不能在此上
  • 运行主机上安装任何东西,我不能创建临时文本文件的过程
的一部分

我可能塞了。

回答

0
@ECHO OFF 
SETLOCAL ENABLEDELAYEDEXPANSION 
(
SET "line=" 
FOR /f "delims=" %%a IN ('sort q22351713.txt') DO (
IF "!line!" neq "%%a" ECHO(%%a 
set "line=%%a" 
) 
)>newfile.txt 

GOTO :EOF 

我用一个名为q22351713.txt的文件来测试。 可生产newfile.txt

不防弹

总是更好的解释一下原来的做,而不是以为这是显而易见的。

+0

我无法在主机上创建任何文本文件。这将在一个集中式发现工具的多个端点上运行,因此只能使用本机(非PowerShell)命令来读取命令,并且与其他建议一样!哦,是的,请告诉我! ;) – delronhubbard

+0

在原文中增加了一些细节。 – delronhubbard

0

脏一批脏...

%COMSPEC% /d /v:on /c "(SET LASTLINE=) & (FOR /f "usebackq tokens=*" %L IN (`DIR /b /s /-p dir1 dir2 dir3 dir3 dir2 dir1 "dir with space" ^| %SYSTEMROOT%\system32\find.exe /i "search_file_name" ^| %SYSTEMROOT%\system32\sort.exe`) DO @((IF /i NOT "{!LASTLINE!}"=="{%~L}" ECHO %~L) & SET "LASTLINE=%~L"))" 

让我们打破这一点...

%COMSPEC% /d /v:on /s /c "..." - 你想一个命令,而不是一个批次,我们需要延迟扩展(/v:on ),因此我们使用Windows命令提示符(%COMSPEC%)的已知可执行文件调用子shell。我们不想运行autoexec.bat(/d),我们想运行该命令并继续前进,而不是离开交互式shell(/c "...")。引用是一个时髦的问题,所以我们尝试了一些“规范”行为(/s

SET LASTLINE= - 清空LASTLINE环境变量

(...) & (...)的任何现有内容 - &&后运行一切,一切不管退出第一位的代码。根据需要使用括号来组合命令。

FOR /f "usebackq tokens=*" %L IN (`...`) DO ... - 运行后引号(usebackq)之间的命令串,并阅读标准输出(FOR /f)的每个行中的所有的单词(tokens=*)到临时变量%L

DIR /b /s /-p dir1 dir2 dir3 dir3 dir2 dir1 "dir with space" - 递归(/s)通过dir1dir2dir3dir with space,文件到标准输出(/b)只打印出完整路径不胜枚举。如果已设置(/-p),则不需要按键来分页输出。需要注意的是,由于FOR弱点是由你来报价目录用特殊字符(如空格),即不要引用单个词的名字。

... ^| ... - 管中的第一命令的所述第二的标准输入的标准输出。我们使用^FOR的反引号内转义|

%SYSTEMROOT%\system32\find.exe /i "search_file_name" - 找到标准输入字符串search_file_name。使用不区分大小写的搜索(/i)。

%SYSTEMROOT%\system32\sort.exe - 排序标准输入和输出到stdout。

DO @(...) - 我们需要运行每行两个命令,所以在括号中,我们组他们。 FOR通常会在每个命令运行之前打印出来,@会抑制这一点。

(IF /i NOT "{!LASTLINE!}"=="{%~L}" ECHO %~L) - 如果我们正在查看的行%~L与我们存储的行不相同!LASTLINE!,请打印我们正在查看的行。再次使用不区分大小写的比较(/i)。我们书夹两个变量与{}处理空值,我们使用延迟扩展(!LASTLINE!而不是%LASTLINE%)每次循环的时间来扩大LASTLINE,不只是当FOR命令第一次看到。

SET "LASTLINE=%~L" - 将我们正在查看的行%~L存储到变量LASTLINE中。

如果您无权访问内置环境变量,则可能没有%SYSTEMROOT%%COMSPEC%。将这些替换为C:\WindowsC:\Windows\System32\cmd.exe,或者更适当地确定您正在扫描的系统的正确位置。