I wan to search for a specific string in the file-path and double that particular string.
Example: if my filepath is C:\Users\XXXX\Desktop\g%h.txt
I want to search and get the % symbol and I need to double it like this C:\Users\XXXX\Desktop\g%%h.txt
How to do this with batch file?
in batchfiles, you have to escape some special chars, so cmd knows NOT to treat them as "special". A percent-sign is escaped with another percent-sign:
#echo off
setlocal enabledelayedexpansion
for %%i in (*.txt) do (
set name=%%i
echo old name: !name!
set name=!name:%%=%%%%!
echo new name: !name!
)
Here is sample to match any txt that contain one or more %
#echo off
setlocal enabledelayedexpansion
for /f "delims=" %%i in ('dir /b /a-d *.txt ^|findstr /i "%%"') do ( set file=%%i
rem Here to remove every % in the name.
echo ren "!file!" "!file:%%=!"
)
exit /b 0
In batch files as it was mentioned above you have to escape % sign with another % sign and file names are no exception. So instead of set file=C:\Users\XXX\Desktop\r%h.txt you must use set file=C:\Users\XXX\Desktop\r%%h.txt.
I wrote a separate batch file that accept two arguments: the first one is naming pattern and the second one is a symbol that needs to be doubled. So, for instance, if you want to double character "r" in all .txt files in the current directory you type
<nameOfTheBatchFile> *.txt r in the command line. Or in your case you can go with
<nameOfTheBatchFile> C:\Users\XXX\Desktop\r%h.txt %
#echo off
setlocal enabledelayedexpansion
set "namingPattern=%1"
set "charToDouble=%2"
for %%i in (%namingPattern%) do (
set "curName=%%i"
set newName=!curName:%charToDouble%=%charToDouble%%charToDouble%!
if "!curName!" neq "!newName!" (
echo Renaming !curName! -^> !newName!
ren "!curName!" "!newName!"
)
)
Related
I need to rename all of these files to the 6 character Part Number(306391) on the 3rd line.
Currently i have:
setlocal enabledelayedexpansion
set first=1
for /f "skip=3 delims= " %%a in (Name.txt) do (
if !first! ==1 (
set first=0
echo %%a > out.txt
ren Name.txt %%a.txt
)
)
Which finds the 6 digit part number and renames the file to the correct name. But breaks if i use *.txt instead of the actual name of the .txt file. I need it to work for all .txt files in the directory.
Surround your for /f loop with another for loop, then reference the outer loop variable in your ren command. You can also eliminate the need for delayed expansion by using if defined for boolean checks. I put in other tweaks here and there. Just ask if you want details.
#echo off
setlocal
for %%I in (*.txt) do (
set first=
for /f "usebackq skip=3" %%a in ("%%~fI") do (
if not defined first (
set first=1
echo %%~nxI ^> %%a.txt
rem // uncomment this when you're satisfied that it works correctly
rem // ren "%%~fI" "%%a.txt"
)
)
)
This method should run faster, specially if the files are large, because just 4 lines of each file are read (instead of the whole file):
#echo off
setlocal EnableDelayedExpansion
rem Process all .txt files
for %%f in (*.txt) do (
rem Read the 4th line
(for /L %%i in (1,1,4) do set /P "line4=") < "%%f"
rem Rename the file
for /F %%a in ("!line4!") do ECHO ren "%%f" "%%a.txt"
)
if my file conatins below text :
sampleA1xxx sampleA2yyyy sampleA3zzzzz ... sampleA4hhhhh
I want to find sampleA4 and display sampleA4hhhh using windows batch script.
Thats is my output should be: sampleA4hhhhh
Could anyone please help me.
take a batch or have a look at GNUWin sed:
>type file
^^sampleA1xxx ^^sampleA2yyyy ^^sampleA3zzzzz ^^sampleA4hhhhh
>sed -r "s/.*(\b\w+4\w+)/\1/" file
sampleA4hhhhh
#echo off
setlocal EnableDelayedExpansion
set target=sampleA4
set len=8
for /F "delims=" %%a in ('findstr "%target%" theFile.txt') do (
for %%b in (%%a) do (
set word=%%b
if "!word:~0,%len%!" equ "%target%" (
echo !word:~%len%!
)
)
)
#ECHO OFF
SETLOCAL
FOR /f "delims=" %%i IN (q17316008.txt) DO SET line=%%i
SET line=%line:^= %
SET line=%line:*sampleA4=sampleA4%
FOR %%i IN (%line:^^= %) DO SET line=%%i&GOTO :done
:done
ECHO %line%
GOTO :EOF
This should do what I gather to be the task. It assumes that the "samplea4" string exists in the file's single line, is case-insensitive and the line doesn't exceed the ~8K limit on line length.
Simply replace the carets with spaces, lop off the leading characters to the first occurrence of the target string, and process that target string as a list; the first element will be the required string, so stop the processing when it's available.
OK, I tried this myself with a similar case and it worked fine:
for /f "tokens=4 delims=^^" %%a in (seperate.txt) do (echo %%a)
pause
Note: This is designed for a batch file, and replace the 4 after "tokens=" with whichever separated text you want to stop at.
Hope this helped,
Yours Mona.
I have and will have files which are named "x_1.txt x_2.txt x_3.txt, ..." my other program where I input these files cannot recognize the order so it sorts like this "x_1.txt , x_101.txt , x_2.txt"). a solution is to rename the files to x00001.txt , x00002.txt , ....
I have so far wrote the .bat file below, but two problems I have which , I'd be very glad if you help me solve them :
1- how can I remove the 'number'.txt from string x_'number'.txt
2- (solved) how can I use the variable of this string to rename the file name ( the rename part of this file is not working!)
cls
setlocal enabledelayedexpansion
set /A count=100000
for %%f in (*.txt) do (
set /a count+=1
set str=!count:~1!
echo !str!
echo %%f
set filename=%%f
set filename=!filename:~0,5! /Comment: here I want to just keep the x_ part which I don't know how"
echo !filename!
set str3=!filname!!str!
echo !str3!
/// ren %%f !str3!.txt /Comment: Here I cannot use the variable str3,
call:renamer %%f !str3!
)
:renamer
ren %1 %2.txt
Thanks in advance
If the following conditions are true:
You want to rename all of your .txt files in the current folder
All of the .txt files have exactly one _ in the name, immediately before the number
None of your file names contain !
Then the following will work
#echo off
setlocal enableDelayedExpansion
for %%F in (*.txt) do for /f "tokens=1,2 delims=_." %%A in ("%%F") do (
set num=0000%%B
ren "%%F" "%%A!num:~-5!.txt"
)
But to eliminate the conditions requires much more complicated code.
Here is one robust solution that should properly rename all files that meet the template.
It allows for multiple _ in the name.
It only renames files with a name that ends with _NNN.txt where NNN is a number
It properly handles ! in the file name.
Note that it will not properly handle numbers that exceeds 99999. It is simple to expand the degree of 0 padding.
#echo off
setlocal disableDelayedExpansion
pushd .
subst #: .
#:
for /f "eol=: delims=" %%F in ('dir /b /a-d *.txt^|findstr /er "_[0-9]*.txt"') do (
set "name=%%~nF"
setlocal enableDelayedExpansion
for /f "eol=: delims=" %%A in ("!name:_=\x!") do (
endlocal
set "file=%%F"
set "name=%%~pA"
set "num=%%~nA"
setlocal enableDelayedExpansion
set "num=0000!num:~1!"
set "name=!name:~1,-1!"
ren "!file!" "!name:\x=_!!num:~-5!.txt"
endlocal
)
)
popd
subst /d #:
Is it possible to remove duplicate rows from a text file? If yes, how?
Sure can, but like most text file processing with batch, it is not pretty, and it is not particularly fast.
This solution ignores case when looking for duplicates, and it sorts the lines. The name of the file is passed in as the 1st and only argument to the batch script.
#echo off
setlocal disableDelayedExpansion
set "file=%~1"
set "sorted=%file%.sorted"
set "deduped=%file%.deduped"
::Define a variable containing a linefeed character
set LF=^
::The 2 blank lines above are critical, do not remove
sort "%file%" >"%sorted%"
>"%deduped%" (
set "prev="
for /f usebackq^ eol^=^%LF%%LF%^ delims^= %%A in ("%sorted%") do (
set "ln=%%A"
setlocal enableDelayedExpansion
if /i "!ln!" neq "!prev!" (
endlocal
(echo %%A)
set "prev=%%A"
) else endlocal
)
)
>nul move /y "%deduped%" "%file%"
del "%sorted%"
This solution is case sensitive and it leaves the lines in the original order (except for duplicates of course). Again the name of the file is passed in as the 1st and only argument.
#echo off
setlocal disableDelayedExpansion
set "file=%~1"
set "line=%file%.line"
set "deduped=%file%.deduped"
::Define a variable containing a linefeed character
set LF=^
::The 2 blank lines above are critical, do not remove
>"%deduped%" (
for /f usebackq^ eol^=^%LF%%LF%^ delims^= %%A in ("%file%") do (
set "ln=%%A"
setlocal enableDelayedExpansion
>"%line%" (echo !ln:\=\\!)
>nul findstr /xlg:"%line%" "%deduped%" || (echo !ln!)
endlocal
)
)
>nul move /y "%deduped%" "%file%"
2>nul del "%line%"
EDIT
Both solutions above strip blank lines. I didn't think blank lines were worth preserving when talking about distinct values.
I've modified both solutions to disable the FOR /F "EOL" option so that all non-blank lines are preserved, regardless what the 1st character is. The modified code sets the EOL option to a linefeed character.
New solution 2016-04-13: JSORT.BAT
You can use my JSORT.BAT hybrid JScript/batch utility to efficiently sort and remove duplicate lines with a simple one liner (plus a MOVE to overwrite the original file with the final result). JSORT is pure script that runs natively on any Windows machine from XP onward.
#jsort file.txt /u >file.txt.new
#move /y file.txt.new file.txt >nul
you may use uniq http://en.wikipedia.org/wiki/Uniq from UnxUtils http://sourceforge.net/projects/unxutils/
Some time ago I found an unexpectly simple solution, but this unfortunately only works on Windows 10: the sort command features some undocumented options that can be adopted:
/UNIQ[UE] to output only unique lines;
/C[ASE_SENSITIVE] to sort case-sensitively;
So use the following line of code to remove duplicate lines (remove /C to do that in a case-insensitive manner):
sort /C /UNIQUE "incoming.txt" /O "outgoing.txt"
This removes duplicate lines from the text in incoming.txt and provides the result in outgoing.txt. Regard that the original order is of course not going to be preserved (because, well, this is the main purpose of sort).
However, you sould use these options with care as there might be some (un)known issues with them, because there is possibly a good reason for them not to be documented (so far).
The Batch file below do what you want:
#echo off
setlocal EnableDelayedExpansion
set "prevLine="
for /F "delims=" %%a in (theFile.txt) do (
if "%%a" neq "!prevLine!" (
echo %%a
set "prevLine=%%a"
)
)
If you need a more efficient method, try this Batch-JScript hybrid script that is developed as a filter, that is, similar to Unix uniq program. Save it with .bat extension, like uniq.bat:
#if (#CodeSection == #Batch) #then
#CScript //nologo //E:JScript "%~F0" & goto :EOF
#end
var line, prevLine = "";
while ( ! WScript.Stdin.AtEndOfStream ) {
line = WScript.Stdin.ReadLine();
if ( line != prevLine ) {
WScript.Stdout.WriteLine(line);
prevLine = line;
}
}
Both programs were copied from this post.
set "file=%CD%\%1"
sort "%file%">"%file%.sorted"
del /q "%file%"
FOR /F "tokens=*" %%A IN (%file%.sorted) DO (
SETLOCAL EnableDelayedExpansion
if not [%%A]==[!LN!] (
set "ln=%%A"
echo %%A>>"%file%"
)
)
ENDLOCAL
del /q "%file%.sorted"
This should work exactly the same. That dbenham example seemed way too hardcore for me, so, tested my own solution. usage ex.: filedup.cmd filename.ext
Pure batch - 3 effective lines.
#ECHO OFF
SETLOCAL
:: remove variables starting $
FOR /F "delims==" %%a In ('set $ 2^>Nul') DO SET "%%a="
FOR /f "delims=" %%a IN (q34223624.txt) DO SET $%%a=Y
(FOR /F "delims=$=" %%a In ('set $ 2^>Nul') DO ECHO %%a)>u:\resultfile.txt
GOTO :EOF
Works happily if the data does not contain characters to which batch has a sensitivity.
"q34223624.txt" because question 34223624 contained this data
1.1.1.1
1.1.1.1
1.1.1.1
1.2.1.2
1.2.1.2
1.2.1.2
1.3.1.3
1.3.1.3
1.3.1.3
on which it works perfectly.
Did come across this issue and had to resolve it myself because the use was particulate to my need.
I needed to find duplicate URL's and order of lines was relevant so it needed to be preserved. The lines of text should not contain any double quotes, should not be very long and sorting cannot be used.
Thus I did this:
setlocal enabledelayedexpansion
type nul>unique.txt
for /F "tokens=*" %%i in (list.txt) do (
find "%%i" unique.txt 1>nul
if !errorlevel! NEQ 0 (
echo %%i>>unique.txt
)
)
Auxiliary: if the text does contain double quotes then the FIND needs to use a filtered set variable as described in this post: Escape double quotes in parameter
So instead of:
find "%%i" unique.txt 1>nul
it would be more like:
set test=%%i
set test=!test:"=""!
find "!test!" unique.txt 1>nul
Thus find will look like find """what""" file and %%i will be unchanged.
I have used a fake "array" to accomplish this
#echo off
:: filter out all duplicate ip addresses
REM you file would take place of %1
set file=%1%
if [%1]==[] goto :EOF
setlocal EnableDelayedExpansion
set size=0
set cond=false
set max=0
for /F %%a IN ('type %file%') do (
if [!size!]==[0] (
set cond=true
set /a size="size+1"
set arr[!size!]=%%a
) ELSE (
call :inner
if [!cond!]==[true] (
set /a size="size+1"
set arr[!size!]=%%a&& ECHO > NUL
)
)
)
break> %file%
:: destroys old output
for /L %%b in (1,1,!size!) do echo !arr[%%b]!>> %file%
endlocal
goto :eof
:inner
for /L %%b in (1,1,!size!) do (
if "%%a" neq "!arr[%%b]!" (set cond=true) ELSE (set cond=false&&goto :break)
)
:break
the use of the label for the inner loop is something specific to cmd.exe and is the only way I have been successful nesting for loops within each other. Basically this compares each new value that is being passed as a delimiter and if there is no match then the program will add the value into memory. When it is done it will destroy the target files contents and replace them with the unique strings
I wrote a script that clear white spaces and write it to the console, but infact do nothing to file name -
#echo off&setlocal EnableDelayedExpansion
for /f "tokens=*" %%A in (
'dir C:\Inetpub\ftproot\MG_REPORTS\MG_PRO_\Network\Frank\ "* *"'
) do (set XX=%%~nxA)&echo ren "%%A" "!XX: =!"
regards,
shamie
Your for loop only sets XX to the last file name encountered. Also it probably loops over all files in the given directory and all file names containing spaces in the current working directory.
I'd do it the following way:
setlocal enabledelayedexpansion
for %%f in (C:\Inetpub\ftproot\MG_REPORTS\MG_PRO_\Network\Frank\*) do (
set "FN=%%~nxf"
set "FN=!FN: =!"
ren "%%f" "!FN!"
)