在 Windows 上列出非符号 link
Listing non symbolic link on Windows
我正在尝试列出特定目录中的非符号 link,然后将其删除。
非符号 links 定义:除了使用命令 MKLINK /H
创建的文件之外的任何文件
为了识别那些非符号 link,我使用了以下方法:
#> fsutil hardlink list %file% | find /c /v ""
当指定的 %file% 是符号时 link 它 return 是一个大于 1 的数字,当它只是一个简单的文件时,它 return 是 1. 到目前为止太好了!
当我需要自动执行此过程并获取这样的 return 来比较它是否大于 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% 变量进行这种归因和比较吗?
您的代码中存在一些问题:
- 您需要 delayed expansion 因为您正在设置(写入) 和 扩展(读取)同一带括号的代码块中的变量
count
(即for /F %%a
循环);
- 在你的
for /F %%a
循环中你需要声明选项 "eol=| delims="
以免 运行 遇到名称以 ;
开头的文件的麻烦(这样会被忽略由于默认的 eol=;
选项)和名称中有 white-space 的那些(由于默认的 [=18,您只会收到第一个 white-space 之前的位置=] SPACE 和 TAB 以及默认选项 tokens=1
(有关详细信息,请参阅 for /?
) ;
dir /B
returns 仅文件名,因此 %%a
实际上指向当前目录中的文件而不是 C:\TEMP\
;要解决这个问题,只需先通过 cd
; 切换到该目录
- 要捕获命令(行)的输出并将其分配给变量,请使用另一个
for /F
循环和 set
;这个循环只会迭代一次,因为 find /C
returns 只有一行;注意下面的转义管道^|
,要求不要马上执行;
- 没有比较运算符
-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
由于内部 for /F
循环总是只迭代一次,我们可以将 if
查询移到里面,从而避免定义一个辅助变量,这是我们唯一需要延迟扩展的变量。
我正在尝试列出特定目录中的非符号链接,然后将其删除。
您的代码存在一些问题。
for /f %%a in ('dir /b %some_dir%') do (
dir /b
不起作用,因为它没有 return 具有完整路径的文件名(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
作为我的测试目录。 hard
是指向 1.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.txt
del /Q f:\test\folder1.txt
del /Q f:\test\folder1.txt
del /Q f:\test\folder1.txt
del /Q f:\test\folder1\file
del /Q f:\test\folder1\test
进一步阅读
- An A-Z Index of the Windows CMD command line - 所有与 Windows cmd 行相关的内容的绝佳参考。
- dir - 显示文件和子文件夹列表。
- enabledelayedexpansion - 延迟扩展将导致变量在执行时而不是在解析时扩展。
- for /f - 根据另一个命令的结果循环命令。
简化方法:
@Echo Off
PushD X:\YourDirectory
For %%a In (*.*) Do (
FSUtil HardLink List %%a|FindStr/VIC:"%%~pnxa">Nul||(Echo=Del "%%~a"))
Pause
如果您对输出感到满意,请删除第 5 行并从第 4 行中删除 'Echo='
我正在尝试列出特定目录中的非符号 link,然后将其删除。
非符号 links 定义:除了使用命令 MKLINK /H
创建的文件之外的任何文件为了识别那些非符号 link,我使用了以下方法:
#> fsutil hardlink list %file% | find /c /v ""
当指定的 %file% 是符号时 link 它 return 是一个大于 1 的数字,当它只是一个简单的文件时,它 return 是 1. 到目前为止太好了!
当我需要自动执行此过程并获取这样的 return 来比较它是否大于 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% 变量进行这种归因和比较吗?
您的代码中存在一些问题:
- 您需要 delayed expansion 因为您正在设置(写入) 和 扩展(读取)同一带括号的代码块中的变量
count
(即for /F %%a
循环); - 在你的
for /F %%a
循环中你需要声明选项"eol=| delims="
以免 运行 遇到名称以;
开头的文件的麻烦(这样会被忽略由于默认的eol=;
选项)和名称中有 white-space 的那些(由于默认的 [=18,您只会收到第一个 white-space 之前的位置=] SPACE 和 TAB 以及默认选项tokens=1
(有关详细信息,请参阅for /?
) ; dir /B
returns 仅文件名,因此%%a
实际上指向当前目录中的文件而不是C:\TEMP\
;要解决这个问题,只需先通过cd
; 切换到该目录
- 要捕获命令(行)的输出并将其分配给变量,请使用另一个
for /F
循环和set
;这个循环只会迭代一次,因为find /C
returns 只有一行;注意下面的转义管道^|
,要求不要马上执行; - 没有比较运算符
-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
由于内部 for /F
循环总是只迭代一次,我们可以将 if
查询移到里面,从而避免定义一个辅助变量,这是我们唯一需要延迟扩展的变量。
我正在尝试列出特定目录中的非符号链接,然后将其删除。
您的代码存在一些问题。
for /f %%a in ('dir /b %some_dir%') do (
dir /b
不起作用,因为它没有 return 具有完整路径的文件名(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
作为我的测试目录。 hard
是指向 1.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.txt
del /Q f:\test\folder1.txt
del /Q f:\test\folder1.txt
del /Q f:\test\folder1.txt
del /Q f:\test\folder1\file
del /Q f:\test\folder1\test
进一步阅读
- An A-Z Index of the Windows CMD command line - 所有与 Windows cmd 行相关的内容的绝佳参考。
- dir - 显示文件和子文件夹列表。
- enabledelayedexpansion - 延迟扩展将导致变量在执行时而不是在解析时扩展。
- for /f - 根据另一个命令的结果循环命令。
简化方法:
@Echo Off
PushD X:\YourDirectory
For %%a In (*.*) Do (
FSUtil HardLink List %%a|FindStr/VIC:"%%~pnxa">Nul||(Echo=Del "%%~a"))
Pause
如果您对输出感到满意,请删除第 5 行并从第 4 行中删除 'Echo='