Batch file attribute check - windows

I'm having a little troubles with my script in .bat. My task is to write a script that will check a file for a few things. I've already defined some of those things, but now I'm stuck. My problem is that I don't know how to define a condition that says: If the file is hidden or read-only, delete this attribute and write some info about the change to the file (some text).
And then I'm having a second problem and that is that the script has always to write something to the file, but when I try to write something to the file (while the script is running) and then I save it, there is always just the thing the script has to write in it. Would somebody please give me some advice? I'm a novice. Thanks a lot for all the responses.
here is the script itself:
#echo off
title file-checking script
set file="file.txt"
set maxbytesize=1
type NUL > file.txt
pause
:loop
if exist file.txt #echo ok> file.txt
if not exist file.txt type NUL > file.txt
FOR /F "usebackq" %%A IN ('%file%') DO set size=%%~zA
if %size% LSS %maxbytesize% (
echo.File is under %maxbytesize% byte
) ELSE (
del file.txt
)
timeout/t 2
goto loop

read HELP FOR and you will notice that checking the attributes is similar to checking the file size
set ATTRS=%%~aA

Use >> instead of > to append data to an existing file, preserving existing content. The > redirection will overwrite any existing content.
You can use the following to test if a file is hidden (after you have proven that it exists):
dir /b /ah file.txt >nul 2>nul && (
echo file is hidden
) || (
echo file is not hidden
)

Related

how to set a text file to be altered by a batch script and output to a .txt and erase the contents of the original text file?

ok so i have a text file i am trying to work on. the batch reverses text.
the batch works fine in cmd>batch.bat i am happy [enter]
yppah ma i
however i have been trying to do this. cmd>batch.bat input.txt [enter]
output.txt
so basically if input.txt says abcdef - output.txt will say fedcba and input.txt will be blank.
i have tried many snippets of code from similar questions on here and none have done well; input.txt is remained unchanged and output.txt remains empty.
when i try to run this to set the file to be run against the batch file,
C:....>batch.bat set /p Build=input.txt
i just get something like C:....>echo txt.tupni=dliuB p/ tes
txt.tupni=dliuB p/ tes
i have tried code from so many different questions on here and they all come out backwards rather than the file contents. i must be making a noob mistake. maybe there is a way i can edit the batch by adding a line in it... something like:
set file=input.txt
...
outfile=output.txt
i think that would simplify things but everytime i try to add set file and outfile to the batch file the whole batch stops working..
heres the batch file. it works it just doesnt like to work anyway other than C:...>batch.bat "sometext"
...
"txetemos"
i know me asking this question will annoy some of the more serious coders here but im doing my best to learn, and i feel like a simple alteration to this code would make it perfect... so heres the batch.
setlocal
if [%1] neq [] goto start
echo Reverse Given Text
echo Usage: %0 text
goto :end
:start
set _len=0
set _str=%*
:: Get the length of the sentence
set _subs=%_str%
:loop
if not defined _subs goto :result
::remove the first char
set _subs=%_subs:~1%
set /a _len+=1
goto loop
:result
set /a _len-=1
for /l %%g in (0,1,%_len%) do (
call :build %%g
)
echo %s%
goto :end
:build
:: get the next character
call set _digit=%%_str:~%1,1%%%
set s=%_digit%%s%
:end
endlocal
i have set sever different methods of implementing a set file= and an >outfile and have had no luck so i tried to add code on the cmd line and i just get
echo "edoc sdrawkcab"
"backwards code"
EDIT:cut out useless code and made the following edit;
EDIT!:
i have found that running batch.bat "text">>log.txt [enter]
makes,,, "txet" being appended into a log.txt... this solves the output to a text file problem..
now i just need to figure out how to get input.txt's text to be ran against batch.bat which will reverse its text using the working batch.bat
i think i can achieve this by making a maincaller "maincaller.bat" file to run this:
batch.bat [set-file=input.txt]>>log.txt
or something similar to result in something like this:;
input.txt reads abra cadabra
i need a command to result in
"arbadac arba" within the >>log.txt file
EDIT* OUTPUT.TXT will now be reffered to as log.txt
I don't quite get, what you want, but here is some code to "revert" a string:
#echo off
setlocal enabledelayedexpansion
set "string=Hello World"
set "reverse="
for /l %%i in (0,1,100) do set "reverse=!string:~%%i,1!!reverse!"
echo %string% - %reverse%

How to sort a file on multiple positions using Windows command line?

I have an index text file, and I'm having trouble sorting it. I've been looking online for an answer, but Google hasn't pulled up anything with multi-positional searches.
Trying to do so with Unix (which would be easy), would be done as
sort inputfile -k1.1 -k3.3 -o outputfile
should accomplish the task, but trying to do so gives me Cygwin errors of already specifying the input twice (UNIX sorts are out!).
I need to sort this index file, either with Windows console applications or Perl on both positions.
Here is the input data:
1925699|0003352_0050003895.pdf|00500003895|0003352
1682628|0003352_0050003894.pdf|00500003894|0003352
1682628|0003352_0050003893.pdf|00500003893|0003352
The desired output is:
1682628|0003352_0050003893.pdf|00500003893|0003352
1682628|0003352_0050003894.pdf|00500003894|0003352
1925699|0003352_0050003895.pdf|00500003895|0003352
I'm currently trying to use:
sort/+1,7 /+32,11 < inputfile > outputfile
But I've failed to get this to be successful. (It only sorts the first parameter.) Again Unix is out of the question, and I can do it in Perl, but can this be done in Windows command line?
#ECHO Off
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "destdir=U:\destdir"
SET "filename1=%sourcedir%\q45575219.txt"
SET "outfile=%destdir%\outfile.txt"
SET "tempfile=%destdir%\tempfile.txt"
(
FOR /f "usebackqdelims=" %%a IN ("%filename1%") DO (
FOR /f "tokens=1,3delims=|" %%s IN ("%%a") DO (
ECHO(%%s%%t^|%%a
)
)
)>"%tempfile%"
(
FOR /f "tokens=1*delims=|" %%a IN (' sort "%tempfile%" ' ) DO ECHO(%%b
)>"%outfile%"
DEL "%tempfile%"
GOTO :EOF
You would need to change the settings of sourcedir and destdir to suit your circumstances.
I used a file named q45575219.txt containing your data for my testing.
Produces the file defined as %outfile%
Uses a temporary file defined as %tempfile%
Read the source file, assigning each line to %%a. Analyse %%a using pipe as a delimiter and select the first and third tokens. Prefix the first and third tokens to the entire line, separated by a pipe and echo into a temporary file.
sort the temporary file, tokenise again on pipe, selecting the first token (before the first pipe) and the rest of the line; output only the rest to the destination file.

Batch file to sort files and list missing

I am trying to write a batch file that would read rows/lines from a txt file containing a list. The batch file would then copy the documents that match, and produce a list of missing files.
So far, the code successfully copies the files that it matches, but it also fills the "Missing.txt" file will exact contents of the input list, rather than simply the missing files.
#echo off
::Requests name of list file to be used by batch file
echo Enter list file name and press enter
set /p var=
mkdir %userprofile%\Desktop\%var%\
set /A lis=1
::Logic to search for files based on contents of list inputted by user at start.
for /f "tokens=*" %%i in (%var%.txt) DO (
call :processline %%i
IF NOT EXIST %%i (echo %%i>>%userprofile%\Desktop\%var%\Missing.txt)
)
pause
::Function called processline
::Assigns a string/value to variable "line"
::Copies a file with name = "line" to the user's desktop
::Renames the file to include a number reference, based on original list being searched
::Increments number for next file to be searched,copies and renamed
:processline
echo line=%*
xcopy /s %*.* %userprofile%\Desktop\%var%
move /Y %userprofile%\Desktop\%var%\%*.pdf %userprofile%\Desktop\%var%\%lis%_%*.pdf
set /A lis=%lis%+1
:eof
I suspect my problem is within the "for" logic, although there might be a way to input missing file names within the processline function.
Any help or advice would be much appreciated.
It's command order: :processline subroutine moves something, maybe including %%i file. I'd use next code snippet:
IF EXIST "%%~i" (
call :processline %%i
) ELSE (
>>"%userprofile%\Desktop\%var%\Missing.txt" echo %%i
)

Writing multiplie lines in a single file using batch file

I am in the middle of a batch file programming and i got stuck in this below script.
(
IF EXIST h:\*.png del h:*.png
IF EXIST h:\*.mov del h:*.mov
) > file.txt
My intention is the script first finds png and mov format in a given drive (in this case h)and then if exists it deletes it. i want to write all process to a txt file (file.txt).
As this is a simple question i really don't want to ask in main SE. I tried first in chat (hello world room). But i didnt get any useful replay regarding it.
Advance thanks for your help
you might try this:
#echo off &SETLOCAL
(
IF EXIST h:\*.png (
DIR /b h:\*.png
del h:\*.png
)
IF EXIST h:\*.mov (
DIR /b h:\*.mov
del h:\*.mov
)) > file.txt
TYPE file.txt
No need for IF. A simple one liner will do, and it is easy to add additional extensions:
>file.txt (for %%X in (png mov) do 2>nul dir /b h:*.%%X && del h:*.%%X)
EDIT
Shoot, it can be made even simpler:
>file.txt dir /b h:*.png h:*.mov && del h:*.png h:*.mov
Or, if you want to specify the list only once:
set "list=h:*.png h:*.mov"
>file.txt dir /b %list% && del %list%

Batch Print - Batch Script - findstr condition in for loop

My problem at hand is to download pdf files and send all of them to the printer.
I download via ftp correctly and all the files go into my local directory:
File Name = FtpScript.ftp
open ftp.domain.com
username
password
!:--- FTP commands below here ---
lcd local/Directory
cd /remote/Directory
binary
mget "*.pdf"
prompt
disconnect
quit
This batch file then calls the ftp script.
File Name = retrieve_print.bat
#ftp -i -s:"C:\Scripts\FtpScript.ftp"
set mm=%date:~4,2%
set dd=%date:~7,2%
set yy=%date:~-4%
IF NOT EXIST {C:\Users\print_test2\print_%mm%_%yy%}( mkdir C:\Users\print_test2\print_%mm%_%yy% )
IF NOT EXIST C:\Users\print_test2\print_%mm%_%yy%\uploaded_%mm%_%dd%_%yy%.txt (
#echo Uploaded Text -- Date: %date% Time : %time% >> C:\Users\print_test2\print_%mm%_%yy%\uploaded_%mm%_%dd%_%yy%.txt
)
IF NOT EXIST C:\Users\print_test2\print_%mm%_%yy%\printed_%mm%_%dd%_%yy%.txt (
#echo Printed Text -- Date: %date% Time : %time% >> C:\Users\print_test2\print_%mm%_%yy%\printed_%mm%_%dd%_%yy%.txt
)
REM LOOP THROUGH PDFs THAT WERE UPLOADED AND INSERT THE NAMES INTO THE UPLOADED_*_*.txt TEXT FILE
FOR %%x in ( C:\Users\print_test2\print_%mm%_%yy%\*.pdf ) DO (
findstr "%%~nxx" C:\Users\print_test2\print_%mm%_%yy%\uploaded_%mm%_%dd%_%yy%.txt
#ECHO Error level = %errorlevel%
#ECHO %%~nxx
#pause
IF NOT %errorlevel% == 0 (
#echo %%~nxx >> C:\Users\print_test2\print_%mm%_%yy%\uploaded_%mm%_%dd%_%yy%.txt
)
)
REM LOOP THROUGH PDFs THAT WERE UPLOADED AND PRINT THEM, THEN INSERT THEM INTO THE PRINTED_*_*.txt TEXT FILE TO SUPPRESS DUPLICATE PRINTS
FOR %%x in ( C:\Users\print_test2\print_%mm%_%yy%\*.pdf ) DO (
findstr "%%~nxx" C:\Users\print_test2\print_%mm%_%yy%\printed_%mm%_%dd%_%yy%.txt
#ECHO Error level = %errorlevel%
#ECHO %%~nxx
IF NOT %errorlevel% == 0 (
rem PRINT FUNCTION
#echo %%~nxx >> C:\Users\print_test2\print_%mm%_%yy%\printed_%mm%_%dd%_%yy%.txt
)
)
The text files generate incorrectly. My thought is that I could loop through the files available in the print_test2/print_%mm%_%yy% directory for all the files that I received via ftp and log it into a text file.
The problem becomes apparent when I try to run the script a second time when the text files have file names in them. I expect the findstr function to give back an %errorlevel% of 0 , but it does not detect the string that is in the text file and appends all the file names again in both my uploaded and printed text files.
Is there a better way of logging the files received and printing the pdfs only once?
Thanks
Your problem is that the %errorlevel% value is taken inside a for, so it is replaced by the value errorlevel had before enter the for loop. To take the current value that errorlevel have in each for iteration you must use Delayed Variable Expansion, that is, enclose the value in exclamation points instead percents: !errorlevel! AND insert this line at begining of your program:
setlocal EnableDelayedExpansion
To make this problem clearer, try this:
set name=Value before FOR
for %%f in (*.pdf) do (
set name=%%f
echo %name%
)
and then try again changing echo %name% by echo !name!.
A few ideas to consider:
I'm not sure that the errorlevel after your FINDSTR command is going to be non-zero just because the string wasn't found.
Even if errorlevel is non-zero, I think that the moment you execute the next command, the new errorlevel from that command gets set.
In your IF statement, you might need to wrap the two sides of your equality check in delimiters, e.g. IF NOT "%errorlevel%" == "0"
You might consider just making your list distinct after you echo all file names into it. It'll save you some logic on the way in. Some code for making a list distinct in DOS is described here: http://www.dullsharpness.com/2010/10/01/create-a-distinct-ordered-list-from-an-unordered-duplicate-list-using-ms-dos/
If you use techniques from #4, you can then just do a directory listing into your file (as follows) and then make unique using techniques in #4.
dir/b C:\Users\print_test2\print_%mm%_%yy%\*.pdf >> C:\Users\print_test2\print_%mm%_%yy%\printed_%mm%_%dd%_%yy%.txt

Resources