batch file (windows cmd.exe) test if a file is a link - windows

How can I test if a file is a symbolic link from a batch file (windows cmd.exe)?
(I would have thought that this was a well phrased question, but stackoverflow appears to want me to write some more, so here it is!)

dir %filename% | find "<SYMLINK>" && (
Do something
)

for /f "tokens=2delims=[]" %%a in ('dir /ad ^|find "<SYMLINKD>"') do echo Symlink: "%%a"
This doesn't work with [] in Symlink names.

Here is an even faster solution as it doesn't require a pipe and also allows access to the original file name either as a relative or absolute path:
#echo off
setlocal EnableDelayedExpansion
set ScriptPath=%~dp0
cd /d "%ScriptPath%"
set "r=%__CD__%"
set SearchTarget=SomePath
for /f "tokens=*" %%a in ('dir /s /b /a:l %SearchTarget% 2^>nul') do (
set "FullPath=%%a"
set "LocalPath=!:%r%=!"
rem local -> [absolute]
echo(!FullPath:%r%=! -^> [%%a]
)
If you don't want to search recursively then remove the /s option for the dir command.

Related

Is there any way for windows batch script or command prompt to list the directories from a certain folder only without including the hard drive?

I tried using dir /b/s *.png to list the directories of all my png files. the results were like this:
D:\Newfolder\test\images\approved\11.png
D:\Newfolder\test\images\approved\12.png
D:\Newfolder\test\images\approved\13.png
D:\Newfolder\test\images\approved\14.png
D:\Newfolder\test\images\approved\15.png
D:\Newfolder\test\images\approved\16.png
D:\Newfolder\test\images\approved\17.png
D:\Newfolder\test\images\approved\18.png
D:\Newfolder\test\images\approved\19.png
D:\Newfolder\test\images\approved\20.png
I want it to be shortened so it will display only starting from the images folder;
images\approved\11.png
images\approved\12.png
images\approved\13.png
images\approved\14.png
images\approved\15.png
images\approved\16.png
images\approved\17.png
images\approved\18.png
images\approved\19.png
images\approved\20.png
is it possible to do?
if it's not, is there any way for me to edit the directories by deleting the first few folder from a generated text file?
say i put dir /b/s *.png > path.txt how do i edit the texts since the list got no whitespaces.
i'm still new to this so i'm not so familiar with much commands but this is as far as my understanding can do.
Assuming this comment in your question:
"I want it to be shortened so it will display only starting from the "images" folder;"
you always want from the images folder, and also assuming the images folder always exists in the path:
#echo off & setlocal enabledelayedexpansion
for /R %%i in (*.png) do (
set "_fp=%%~i"
echo !_fp:*\images\=images\!"
)
pause
Or to explicitly ensure you only include paths with \images\ in the path:
#echo off & setlocal enabledelayedexpansion
for /F "delims=" %%i in ('dir /b /s *.png ^| findstr \images\') do (
set "_fp=%%~i"
echo !_fp:*\images\=images\!"
)
pause
example of using pushd:
#echo off & setlocal enabledelayedexpansion
pushd "%~1"
for /F "delims=" %%i in ('dir /b /s *.png ^| findstr \images\') do (
set "_fp=%%~i"
echo !_fp:*\images\=images\!"
)
pause
popd
So the above you can run from cmd and simply pass the path you want the script to run in as script_name.cmd "C:\some path\here"

Display directory structure using relative paths

I want to generate a file that contains the directory structure of a given directory, as relative paths. Currently I have the following batch file:
#echo off
pushd "C:\TEST"
dir /AD /B /ON /S
popd
Its current output is this:
C:\TEST\one
C:\TEST\three
C:\TEST\two
C:\TEST\one\a
C:\TEST\three\d
C:\TEST\three\e
C:\TEST\three\f
C:\TEST\two\b
C:\TEST\two\c
I want the output to be:
one
three
two
one\a
three\d
three\e
three\f
two\b
two\c
EDIT: this question is not a duplicate. The other question shows files exclusively, now I need to get directories exclusively (not mixed with files).
#echo OFF
SETLOCAL enabledelayedexpansion
SET "targetdir=c:\106x"
pushd "%targetdir%"
FOR /f "delims=" %%a IN ('dir /AD /B /ON /S') DO (SET "dirname=%%a"&ECHO(!dirname:%targetdir%\=!)
popd
GOTO :EOF
This should work for you provided the directoryname does not contain !
The directorynames are applied to %%a and transferred to dirname for manipulation. The target directoryname + a closing \ are then replaced by nothing for display.

Can I get the DOS for command to substitute the file owner and creation times?

I am running the following command in cmd.exe to list files recursively...
for /r %i in (*) do #echo %~xi %~zi %~ti %~fi
.. to get output like this:
.ext 187392 15/01/2014 14:16 C:\path\to\filename\f.ext
But can I get the file owner added to this output? I'm looking for the same owner that dir /q gives me. I'd also like to get the file creation time rather than the last-access time which I believe %~ti is giving me.
If I can't do this using for, is there a way I can do it using a combination of for and dir?
< lang-dos -->
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
for /r "%sourcedir%" %%i in (*.pdf) do (
SET "grab="
FOR /f "skip=5tokens=1,2,4delims=\ " %%a IN ('dir /q /tc /-c "%%~fi"') DO IF NOT DEFINED grab (
SET grab=Y
echo %%~xi %%~zi %%a %%b %%c %%~fi
)
)
GOTO :eof
You would need to change the setting of sourcedir to suit your circumstances. I used a filemask of *.pdf to make the test results more legible. You want different? Change it!

How to create file in partially known folder name using batch file

I want to create a 0 byte file names dblank in a specific directory C:\Users\myUser\*.data\.
echo. 2>"C:\Users\myUser\*.data\dblank.txt"
The * sign in the above command refers to any letters or numbers. I do not know. How can I refer to any letters or numbers in my batch code?
Maybe this:
setlocal enableextensions
for /D %%i in (C:\Users\myUsers\*.data) do copy nul "%%~i\dblank.txt"
endlocal
You can omit setlocal/endlocal if command extensions are already enabled (cmd /E:on).
This works on every existing *.data folder, if any.
#echo off
for /f "delims=" %%f in ('dir /b /s /ad C:\Users\myUser\*.data') do echo. 2>"%%f\dblank.txt"
EDIT
Filter results:
#echo off
for /f "delims=" %%f in ('dir /b /s /ad C:\Users\myUser\*.data^|findstr /r "\\[0-9a-zA-Z]*\.data$"') do (
echo. 2>"%%f\dblank.txt"
)

Renaming files by folder hierarchy

I have many files with the following structure:
1969/ar/1.jpg
1969/ar/2.jpg
1969/he/1.jpg
1969/he/2.jpg
1969/en/1.jpg
1969/en/2.jpg
1970/ar/1.jpg
etc...
I want to rename all of them, with one command, to one directory, while their names reflect their original folder location.
1969_ar_1.jpg
1969_ar_2.jpg
1969_he_1.jpg
1969_he_2.jpg
1969_en_1.jpg
1969_en_2.jpg
1970_ar_1.jpg
etc...
Is it possible to do so with one command or a batch file?
Thanks!
You may do that to move the files to the base folder with this command-line:
for /R %a in (*) do #set f=%a& set f=!f:%cd%\=!& move "%a" !f:\=_!
Execute it from the folder that contain the 1969, 1970... folders. IMPORTANT!: Delayed Expansion must be active in order for this line to work, so you must previously activate it executing cmd.exe with /V switch this way: cmd /V.
For example:
>xcopy test backup /s
test\1969\ar\1.jpg
test\1969\ar\2.jpg
test\1969\en\1.jpg
test\1969\en\2.jpg
test\1969\he\1.jpg
test\1969\he\2.jpg
test\1970\ar\1.jpg
7 File(s) copied
>cd test
>dir /B
1969
1970
>for /R %a in (*) do #set f=%a& set f=!f:%cd%\=!& move "%a" !f:\=_!
>dir /B
1969
1969_ar_1.jpg
1969_ar_2.jpg
1969_en_1.jpg
1969_en_2.jpg
1969_he_1.jpg
1969_he_2.jpg
1970
1970_ar_1.jpg
Modify the line this way to move the files to another folder:
for /R %a in (*) do #set f=%a& set f=!f:%cd%\=!& move "%a" "\other\folder\!f:\=_!"
Or via this Batch file:
#echo off
setlocal EnableDelayedExpansion
for /R %%a in (*) do set f=%%a& set f=!f:%cd%\=!& move "%%a" "\other\folder\!f:\=_!"
Run this from the base of the tree that contains all *.jpg files.
Change the target folder to where you want the files to go:
Test it on some samples first.
#echo off
for /f "delims=" %%z in ('dir "*.jpg" /b /s /a-d ') do (
for %%a in ("%%~dpz%\.") do (
for %%b in ("%%~dpa\.") do (
ren "%%z" "%%~nxb_%%~nxa_%%~nxz"
move "%%~dpz\%%~nxb_%%~nxa_%%~nxz" "c:\target\folder"
)
)
)
pause
try this (look at the output and remove the word echo before move, if it is OK):
#echo off &setlocal
for /d %%i in (19* 20*) do (
cmd /c "for /r "%%i" %%j in (*.jpg) do #for %%k in ("%%~dpj.") do #echo move "%%~j" "%%i_%%~nk_%%~nxj""
)

Resources