Dos dir mask, want "*.xxx" and not "*.xxxzz" - windows

In my directories, I have file names like *.xxx and also *.xxxzz
When I do dir /s/b "*.xxx" I get *.xxxzz files in my list. I do NOT get these results in a "Take Command" console, but I do in a cmd console.
How do I get cmd to give me only *.xxx files?

With the DIR command, when you specify a mask containing an extension of exactly three characters, you will get matches of files that contain extensions with three or more characters, so long as the first three characters match the extension you originally specified.
I have no idea why it works this way, but at least the behavior is consistent nearly everywhere in the Windows API where you can specify a file search pattern. I can only assume it has something to do with support for long file extensions (i.e., file names that don't comply with the old DOS 8.3 rule).
But, you can get around the behavior in two ways:
A mask that specifies a file extension with one, two, or more than three characters will return only files with extensions of exactly the specified length.
So, for example, dir /s/b "*.xx" will give you only files with the extension .xx, and dir /s/b "*.xxxzz" will give you only files with the extension .xxxzz.
You can use the question mark wildcard character, instead of the asterisk. Asterisks mean "replaced by zero or more characters", while question marks mean an exact substitution of the question mark with a single character.

I suspect you're running into a problem because of the way Windows (older versions, at least) generated a short 8.3 filename to improve compatibility with old programs. You can probably confirm this by doing dir /x *.xxx in the directory where your *.xxxzz files exist.
I'm not sure if there's a way around it from the limited Windows command line tools. There should probably have been a switch on the dir command to force consideration only of long filenames, but I don't see one.
You may be able to solve your problem by disabling short filenames on that volume, if you're sure you don't need them for any ancient software you're running.
I haven't tried that myself, so maybe the short names already generated will continue to exist after you follow those instructions. If so, you might be able to fix it by copying the tree you're working with to a new location.

The fact is that unless the system has been set up to not generate 8.3 names, every file or directory with a long filename will also have an 8.3 alias. At least one - with some of the warped constructs in use in later editions, there many be many aliases.
Academically, since it's a matter of opinion (and hence outside of SO's bailiwick) it could be argued that your alternative command processor is not producing the correct results since it apparently ignores the short filename. Which is "correct" is debatable - what suits in one application may not in another. The easiest and most logical way of course is to have an option - but the chances of the major player in the debate incorporating such a facility at this stage amount to well,Buckley's
Here's a routine that may suit. It's not bullet-proof as it will have problems with some "poison characters" (those with special meaning for the standard command-processor cmd.exe(A windows application that emulates and enhances many of the facilities available in DOS, and normally, though technically-incorrectly, called "DOS" by the politically-incorrect for the sake of brevity.))
#ECHO Off
SETLOCAL
SET "mask=%~1"
IF "%mask:~-4,1%"=="." ECHO(%mask:~-3%|FINDSTR /L "* ." >NUL&IF ERRORLEVEL 1 (
FOR /f %%a IN ('dir /s/b "%mask%"') DO IF /i "%%~xa"=="%%~sxa" ECHO(%%a
GOTO :EOF
)
dir /s/b "%mask%"
GOTO :EOF

Related

Windows cmd, file rename and rearange

I'm a biologist, and sometimes I have to work with quite a lot of files, which are arranged not in an optimal way by someone.
Can you give me a tip on the following task?
There are folders
D:\.......\folder1\subfolder(1....)\subsubfolder(1.....) \SOMEtext_exactword(1.....)
(the last one are files without extension)
Can I create in windows cmd something like
D:\.......\folderEXACTWORD1\(subfolder1_subsubfolder1_SOMEtext_exactword1,
subfolder2_subsubfolder2_SOMEtext_exactword1,
subfolder3_subsubfolder3_SOMEtext_exactword1)
(the last one are files without extension again)
Meaning to find all files, containing "string" in their name in few sub folders, copy them into the specific folder and rename them, so they contain their parent file location in their name now.
I guess there should be a way to do it in a linux, though I am not a linux user and not a good (not at all actually) coder myself. Though I can handle some work, so I would be happy if someone can give me a tip whats the easiest way to do what I want. Or what can I search - I tried to search, but maybe I am missing some right words to look for.
Your question is very unclear, but here is more or less something that does this, you have to still define a few more items to make sure your find the correct files in locations and move them accordingly.
#echo off
setlocal enabledelayedexpansion
set mydir="D:\somedir\somedir\someotherdir\
for %%a in (%mydir%) do set "name=%%~nxa"
echo %name%
for /r %%i in (*string*) do (set "file=%%i"
echo move "!file!" "C:\somedir\!name!")
)
)
endlocal
Well. Someone elsewhere has given me advice and it worked. In total commander, you can do it with multi-rename tool and flags [P] and [G] which will allow you to add parent and grandparent directory name.
Well. I guess there is nothing wrong with having this topic with answer from myself, but I will be ok if it is deleted :)
Though I will be still interested if it can be done from cmd, just out of curiosity.

Batch Script wanted (windows). find substrings in text file, and make specific changes based on positions of characters

(This is a Windows environment by the way.)
I'm new to batch scripting and, I'll be honest, I'm struggling.
I've done a lot of googling and spent a lot of time trying to work this out but I'm not getting very far. I thought I'd throw this out to the community to see if anyone was up to the challenge. :)
First up, this is for my own personal use and curious interest to see if this is possible without writing a new .exe in a more... conventional language.
This is it : I'm using some software which is essentially portable. the only downside is that it writes to a .ini file very specific file paths which may not necessarily be correct if using another computer.
For example, if I run the software from a USB in Computer A, that computer might see the USB drive as D: and save a path in the ini as Path=D:\portables\soft1\saves\file1.xyz. But if I later use the same USB in Computer B which assigns a different letter to the drive (let's say E:) then the software will throw its toys out of the pram, because it's looking on the wrong drive for what should be now on E:. And if I run the software from a network drive or even cloud storage then the path's get even more complex.
I want to run a script that might, before running the software's .exe, look in the .ini for all instances of such filepaths and replace the full path with simply Path=.\saves\file1.xyz. The software is happy with this and can find what it needs to.
This is the ONLY thing that prevents the software being portable.
This is how I thought it would be done...
Search each line in the .ini, one at a time, to see if contains the
substring "Path="
If it finds it do the following...
a. Store the position of the character AFTER the "=" in "Path=" in a variable (let's say it's vPosA=6)
b. Search the same line for another substring "\saves\" and if it finds that then store the position of the character BEFORE the first "\" in another variable (let's say vPosB=18).
c. If vPosA and vPosB are both >0 then do the following
i. Replace all the characters on that line, from vPosA to vPosB, to "."
ii. Reset vPosA and vPosB both back to "0"
Go to the next line and repeat the process until the end of file is reached, then overwrite the .ini with the changes.
I'm looking forward to seeing what people come up with. Like I said, it's curiosity driving this. If I get no answer, or it's way way too complex I may just write the thing in VB or something and use a .bat to run it before running the software. The advantage of having it as a Batch Script is that it could shared with the software's community and the script is plain to see for all. With a compiled .exe people won't be able to see what's in it and would therefore, justifiably, distrust it.
This should do:
#echo off
setlocal enabledelayedexpansion
(for /f "tokens=*" %%a in (in.txt) do (
set "line=%%a"
if /i "!line:~0,5!"=="Path=" set "line=Path=!line:*\saves=.\saves!"
echo !line!
))>out.txt
type out.txt
Read every line, check if the first five characters are Path= (ignoring capitalization), if yes replace all from start to (including) "\saves" with ".\saves, append the string Path= in front of it. Print the line. Redirect the whole thing to another file.
You can then delete the original file and rename the new file to the old name.
NOTE: this ignores empty lines. It's possible to keep them with some more code.

Documented behavior for multiple backslashes in Windows paths

Apparently, Windows (or at least some part of Windows) ignores multiple backslashes in a path and treats them as a single backslash. For example, executing any of these commands from a command prompt or the Run window opens Notepad:
C:\Windows\System32\Notepad.exe
C:\Windows\System32\\Notepad.exe
C:\Windows\System32\\\Notepad.exe
C:\Windows\System32\\\\Notepad.exe
C:\\Windows\\System32\\Notepad.exe
C:\\\Windows\\\System32\\\Notepad.exe
This can even work with arguments passed on the command line:
notepad "C:\Users\username\Desktop\\\\myfile.txt"
Is this behavior documented anywhere? I tried several searches, and only found this SO question that even mentions the behavior.
Note: I am not asking about UNC paths (\\servername), the \\?\ prefix, or the \\" double-quote escape.
Note: I stumbled upon this behavior while working with a batch file. One line in the batch file looked something like this:
"%SOME_PATH%\myapp.exe"
After variable expansion, the command looked like:
"C:\Program Files\Vendor\MyApp\\myapp.exe"
To my surprise, the batch file executed as desired and did not fail with some kind of "path not found" error.
In most cases, Win32 API functions will accept a wide range of variations in the path name format, including converting a relative path into an absolute path based on the current directory or per-drive current directory, interpreting a single dot as "this directory" and two dots as "the parent directory", converting forward slashes into backslashes, and removing extraneous backslashes and trailing periods.
So something like
c:\documents\..\code.\\working\.\myprogram\\\runme.exe..
will wind up interpreted as
c:\code\working\myprogram\runme.exe
Some of this is documented, some is not. (As Hans points out, documenting this sort of workaround legitimizes doing it wrong.)
Note that this applies to the Win32 API, not necessarily to every application, or even every system component. In particular, the command interpreter has stricter rules when dealing with a long path, and Explorer will not accept the dot or double-dot and typically will not accept forward slashes. Also, the rules may be different for network drives if the server is not running Windows.
There is no consequence because you can't even name a file or folder with a backslash. So multiple consecutive backslashes will always be seen as one separator in the path.

WMIC process list bug?

i recently found that wmic (windows management intrumentation command-line) existed :D, which is far better w/ more options than the regular "tasklist" in cmd that saves me time.
But i found a problem when exporting to .txt, is this: supposed to be that way? Because the first two letters of each line, are in the final part of each line... like here: .. is this a known "glitch/bug"? i couldn't find anything online that demonstrated this..
You have no problems with your files. You have a problem with notepad. There is a limit of 1024 characters in the length of the line. The 1025th character and following are moved to next line.
I'd suggest your problem is related to the fact that WMIC outputs unicode. I'd suggest piping the output through MORE.
I use `Editplus as an editor which appears to accept a unicode file quite happily. I'd suggest your editor isn't quite up to snuff.
MORE is a supplied utility - try more /? from the prompt for more info.
Processing your WMIC output through more is
wmic whatever | more >textfile
you might also try
for /f "delims=" %%a in ('wmic whatever') do >>textfile echo(%%a
(as a batch line - reduce %% to % to use from the prompt)
Notepad is a wannabe WP, wannabe editor. Tries to do both and does neither particularly well. Often gives problems in batch work. Since it's a supplied utility, there's no incentive to improve it - Microsoft simply doesn't have the funds.
Hence the availability of software from other vendors to do the task required.

Space before command circumvents DOSKEY

I wanted keep my users from running "dir" in the command line, so I used DOSKEY to alias "Dir" to "CLS". The testers found out that putting a space before "DIR" will circumvent the alias.
I've tried to put a space before "DIR" when setting up the DOSKEY, but the command prompt ignores the white space.
Anyone found a way of making DOSKEY acknowledge spaces?
Thanks.
Deny your users the List Directory contents permission on all relevant locations. That's probably the easier way. That way they can run dir but it won't be of any use.
I'm not even trying to figure out why you want such a thing, though.
Regarding doskey: As you noticed, macro substituion is done literally and only at the beginning of the command line. So what do you want to do? Create macros for dir to cls with 1, 2, 3, ..., 8188 spaces before it?
Blacklisting almost never works, and it certainly isn't going to in this case. You can, for example, list the files in a directory simply by pressing TAB repeatedly.
Instead, use whitelisting. Write a console application that takes user input, checks that the input is a command that the user is allowed to run, and if so, passes that command to the shell - or, better still, implement the "approved" commands yourself, so that (a) there can't be any trickery with special characters, and (b) you can remove cmd.exe from the approved applications list - you are using software restriction policy, right?
Even if you could figure out how to make your DOSKEY macro idea work (I don't think you can), it would be pointless. Your users could easily circumvent the restriction by creating the following batch file:
#dir %*
DOSKEY macros do not work within batch files, so there is nothing to stop the batch file from executing. And your users could name the batch file anything they want, so you would have a devil of a time policing.

Resources