在Windows上列出非符号链接

时间:2016-08-29 19:18:53

标签: windows batch-file mklink

我试图列出特定目录中的非符号链接,然后将其删除。

非符号链接定义:除了使用命令MKLINK / H

创建的文件之外的任何文件

为了识别那些非符号链接,我使用了以下方法:

#> fsutil hardlink list %file% | find /c /v ""

当指定的%file%是符号链接时,它返回一个大于1的数字,当它只是一个简单的文件时,它返回1.到目前为止一直这么好!

当我需要自动执行此过程时,我的问题就开始了,并且如果它大于1则返回比较

这就是我试图获得运行属性的代码:

@echo off    
set some_dir=C:\TEMP\    
for /f %%a in ('dir /b %some_dir%') do (
    set count=fsutil hardlink list %%a | find /c /v ""
    if %count% -EQU 1 del /Q %%a        
)

有人会解释我如何进行%count%变量的归属和比较吗?

3 个答案:

答案 0 :(得分:2)

我正在尝试列出特定目录中的非符号链接,然后将其删除。

您的代码存在一些问题。

for /f %%a in ('dir /b %some_dir%') do (

dir /b不起作用,因为它没有返回带有完整路径的文件名(需要作为fsutil的输入)

改为使用dir /b /s

set count=fsutil hardlink list %%a | find /c /v ""

这并不算什么明智。

使用其他for /f并解析fsutil的输出,以便设置变量。

if %count% -EQU 1 del /Q %%a

这有两个错误。您需要使用延迟扩展来正确评估count。将%count%替换为!count!。同时删除-。将-EQU替换为EQU

尝试以下批处理文件。

<强> TEST.CMD:

@echo off 
setlocal enabledelayedexpansion
set some_dir=C:\TEMP\
for /f %%a in ('dir /b /s %some_dir%') do (
  for /f %%b in ('fsutil hardlink list %%a ^| find /c /v ""') do (
    set count=%%b
    if !count! EQU 1 echo del /Q %%a        
    )
  )
endlocal

注意:

  • 如果您对结果感到满意,请移除echo

示例用法和输出:

我使用f:\test\folder1作为我的测试目录。 hard1.txt的硬链接。

F:\test>dir f:\test\folder1
 Volume in drive F is Expansion
 Volume Serial Number is 3656-BB63

 Directory of f:\test\folder1

29/08/2016  21:40    <DIR>          .
29/08/2016  21:40    <DIR>          ..
21/08/2016  09:46                 0 1.txt
21/08/2016  09:46                 0 2.txt
21/08/2016  09:46                 0 3.txt
21/08/2016  09:46                 0 4.txt
21/08/2016  09:46                 0 5.txt
29/08/2016  21:38    <SYMLINK>      file [f:\d]
21/08/2016  09:46                 0 hard
29/08/2016  21:38    <SYMLINKD>     test [f:\d]
               7 File(s)              0 bytes
               3 Dir(s)  1,764,846,960,640 bytes free

F:\test>test
del /Q f:\test\folder1\2.txt
del /Q f:\test\folder1\3.txt
del /Q f:\test\folder1\4.txt
del /Q f:\test\folder1\5.txt
del /Q f:\test\folder1\file
del /Q f:\test\folder1\test

进一步阅读

答案 1 :(得分:1)

您的代码中存在一些问题:

  • 您需要delayed expansion,因为您正在设置(编写)在同一个带括号的代码块(即var init = ...中扩展(读取)变量count } loop);
  • for /F %%a循环中,您需要说明选项for /F %%a,以免在名称以"eol=| delims="开头的文件遇到问题(由于默认{{ 1}} option)和名称中有空格的那些(由于默认的; SPACE TAB,你只会在第一个空格之前收到位置和默认选项eol=;(有关详细信息,请参阅delims);
  • tokens=1仅返回文件名,因此for /?实际指向当前目录中的文件而不是dir /B;要解决此问题,只需先通过%%a;
  • 更改到该目录
  • 捕获命令(行)的输出并将其分配给变量,使用另一个C:\TEMP\循环和cd;这个循环只会迭代一次,因为for /F只返回一行;请注意下面的转义管道set,这不需要立即执行;
  • 没有比较运算符find /C,您需要删除^|以检查是否相等;
  • 使用引用的-EQU语法是个好主意,因为它对于有毒字符最强大;
  • 文件和目录路径通常应该引用,因为它们可能包含令牌分隔符或其他有毒字符;

这是固定的脚本:

-

甚至可以简化:

set

由于内部@echo off setlocal EnableDelayedExpansion pushd "C:\TEMP\" || exit /B 1 for /F "eol=| delims=" %%a in ('dir /B "."') do ( for /F %%b in (' fsutil hardlink list "%%a" ^| find /C /V "" ') do ( set "count=%%b" ) if !count! EQU 1 del "%%a" ) popd endlocal 循环仅迭代一次,我们可以在内部移动@echo off pushd "C:\TEMP\" || exit /B 1 for /F "eol=| delims=" %%a in ('dir /B "."') do ( for /F %%b in (' fsutil hardlink list "%%a" ^| find /C /V "" ') do ( if %%b EQU 1 del "%%a" ) ) popd 查询,从而避免定义辅助变量,这是我们唯一需要延迟扩展的辅助变量。

答案 2 :(得分:0)

简化方法:

@Echo Off
PushD X:\YourDirectory
For %%a In (*.*) Do (
    FSUtil HardLink List %%a|FindStr/VIC:"%%~pnxa">Nul||(Echo=Del "%%~a"))
Pause

当您对输出删除第5行以及“Echo =&#39;”满意时从第4行