Windows CLI相当于" sort -u"

时间:2014-03-12 12:34:07

标签: windows sorting unique command-line-interface

我需要在Windows CLI中采用一种等效的方式,以便在Linux / UNIX中通过管道传输来显示唯一值。

我不认为有这样的命令,我可以收集的信息,还有另一种方法吗?

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

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

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

在Windows中执行相同操作显然更加困难,因为:

  • 它必须是您在Windows命令提示符(cmd.exe)中使用的本机只读命令/脚本字符串
  • 我无法在
  • 上运行的主机上安装任何内容
  • 我无法创建临时文本文件作为流程的一部分

4 个答案:

答案 0 :(得分:1)

  1. Microsoft在Windows 10中向/unique添加了sort.exe切换,但忘记更新其文档。我在Windows 7,Windows 8.1和Windows 10 v1709上测试了此开关。它出现在后者中,但在前两个中没有出现。

    因此,sort.exe /unique相当于UNIX sort -u

  2. PowerShell已经有一个支持Sort-Object切换的-Unique cmdlet。更好的是,默认情况下,PowerShell为sort定义了别名Sort-Object,因此| sort -unique几乎就是您所需要的。

答案 1 :(得分: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

不是防弹

总是更好地解释原作所做的事情而不是假设它是显而易见的。

答案 2 :(得分: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命令提示符的已知可执行文件调用子shell({{1 }})。我们不想运行autoexec.bat(%COMSPEC%),我们想要运行命令并继续前进,而不是留下交互式shell(/d)。引用是一个时髦的问题,所以我们尝试一些“标准化”行为(/c "..."

/s - 清空SET LASTLINE=环境变量

的所有当前内容

LASTLINE - 运行(...) & (...)之前的所有内容以及&之后的所有内容,无论第一位的退出代码如何。根据需要使用括号分组命令。

& - 在反引号(FOR /f "usebackq tokens=*" %L IN (`...`) DO ...)之间运行命令字符串,并将每行stdout(usebackq)中的所有单词(tokens=*)读入临时变量{ {1}}。

FOR /f - 递归(%L)枚举DIR /b /s /-p dir1 dir2 dir3 dir3 dir2 dir1 "dir with space"/sdir1dir2,仅打印文件的完整路径到stdout(dir3)。如果已设置(dir with space),则不要求按键来分页输出。请注意,由于/b的缺陷,您需要引用具有特殊字符(例如空格)的目录,即不引用单字名称。

/-p - 将第一个命令的stdout传递给第二个命令的stdin。我们使用FOR... ^| ...的反引号中转义^

| - 在stdin中找到字符串FOR。使用不区分大小写的搜索(%SYSTEMROOT%\system32\find.exe /i "search_file_name")。

search_file_name - 对stdin进行排序并写入stdout。

/i - 我们需要为每一行运行两个命令,因此我们将它们放在括号中。 %SYSTEMROOT%\system32\sort.exe通常在运行它之前打印每个命令,DO @(...)会抑制它。

FOR - 如果我们查看的@行与我们存储的行(IF /i NOT "{!LASTLINE!}"=="{%~L}" ECHO %~L)不同,请打印我们正在查看的行。同样,使用不区分大小写的比较(%~L)。我们使用!LASTLINE!对两个变量进行了处理以处理空值,并且我们使用延迟展开(/i而不是{})来在每次循环时展开!LASTLINE!,而不仅仅是首先看到%LASTLINE%命令。

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

如果您无权访问内置环境变量,则可能没有%~LLASTLINE。将这些替换为%SYSTEMROOT%%COMSPEC%,或者更恰当地确定您正在扫描的系统的正确位置。

答案 3 :(得分:0)

下载 cygwin 实用程序,它是 windows 下简单的 Linux 终端。 它允许在 Windows 中执行任何 Linux 命令。 你有 sort -u 那里。

相关问题