windows batch file change blank field to value - windows

I am writing a windows script to read in a txt file with 9 columns of data
I want to write this data out to a csv file to be loaded into a database.
I have found that one column is sometimes blank, so I would like to enter code 'rdp'
another column has mostly numbers, but for reason some values are a '.' (presumably indicating value less than 1. I would like to change these values to '0'
my code
for /F %%b in (c:\ts_users\newfiles_list.txt) do (
for /F "tokens=1,2,3,4,5,6,7,8,9" %%i in (%%b) do (
echo %%i,%%j,%%k,%%l,%%m,!idle!,%%o %%p,%%q >>%%~nb.csv
)
)
this manages to read in the txt file, then write it out as a csv.
column k is sometimes empty, column n sometimes has a '.'
I have tried variations of
set var=rdp
if %%k="" then set !k:=!var!
which doesnt work, so I a little stumped (after googling internet for days)
current input
201401241611 USERNAME SESSIONNAME ID STATE IDLE TIME LOGON TIME eu1ptsw002
201401241611 julie.noble rdp-tcp#9 3 Active 18 24/01/2014 14:24 eu1ptsw002
201401241611 svc.perfmon18 7 Disc 3 24/01/2014 14:15 eu1ptsw002
201401241611 reto.hofstetter 10 Disc 40 24/01/2014 10:57 eu1ptsw002
201401241611 lester.valentin 14 Disc 1:16 24/01/2014 11:53 eu1ptsw002
201401241611 philippe.bachmann 15 Disc 2 24/01/2014 12:45 eu1ptsw002
201401241611 patrik.soderlund rdp-tcp#2 21 Active 24 24/01/2014 07:42 eu1ptsw002
current output
201401241611,USERNAME,SESSIONNAME,ID,STATE,,TIME LOGON,TIME
201401241611,julie.noble,rdp-tcp#9,3,Active,,24/01/2014 14:24,eu1ptsw002
201401241611,svc.perfmon18,7,Disc,3,,14:15 eu1ptsw002,
201401241611,reto.hofstetter,10,Disc,40,,10:57 eu1ptsw002,
201401241611,lester.valentin,14,Disc,1:16,,11:53 eu1ptsw002,
201401241611,philippe.bachmann,15,Disc,2,,12:45 eu1ptsw002,
201401241611,patrik.soderlund,rdp-tcp#2,21,Active,,24/01/2014 07:42,eu1ptsw002
required output
201401241611,USERNAME,SESSIONNAME,ID,STATE,,TIME LOGON,TIME
201401241611,julie.noble,rdp-tcp#9,3,Active,18,24/01/2014 14:24,eu1ptsw002
201401241611,svc.perfmon18,rdp,7,Disc,3,24/01/2014 14:15,eu1ptsw002
201401241611,reto.hofstetter,rdp,10,Disc,40,24/01/2014 10:57,eu1ptsw002,
201401241611,lester.valentin,rdp,14,Disc,1:16,24/01/2014 11:53,eu1ptsw002
201401241611,philippe.bachmann,rdp,15,Disc,2,24/01/2014 12:45,eu1ptsw002
201401241611,patrik.soderlund,rdp-tcp#2,21,Active,24,24/01/2014 07:42,eu1ptsw002

#echo off &setlocal disableDelayedExpansion
for /f "delims=" %%a in (file) do (
set "line=%%~a"
setlocal enabledelayedexpansion
set "line=!line:,.,=,0,!"
set "line=!line:,,=,rdp,!"
echo(!line!
endlocal
)

Related

Batch file doesn't insert text from another file

I am working in Windows 10 and I have text files resulting from another process that I want to edit using a batch file. I've shortened the example, File-1 (shown below with line numbers) for this post. They are all formatted this way, but much longer and with more sections:
1 Album 1 - 1982,,,
2 ('Song 1'),
3 ('Song 2'),
4 |===================|
5 Album 2 - 1978,,,
6 ('Song 1'),
7 ('Song 2'),
After each line with a string of 3 commas (lines 1 and 5) I want to insert two new lines of text from File-2 before the existing lines in File-1 (lines 2 and 6).
The two lines in File-2 to insert are:
NEW LINE 1
NEW LINE 2
The desired output would then be:
1 Album 1 - 1982,,,
2 NEW LINE 1
3 NEW LINE 2
4 ('Song 1'),
5 ('Song 2'),
6 |===================|
7 Album 2 - 1978,,,
8 NEW LINE 1
9 NEW LINE 2
10 ('Song 1'),
11 ('Song 2'),
The closest I've come so far as an experiment is a batch file (that I found and adapted) that finds the 3 commas and replaces them with 3 dots.
#echo off &setlocal
set "search=,,,"
set "replace=..."
(for /f "delims=" %%i in (a.txt) do (
set "word=%%i"
setlocal enabledelayedexpansion
set "word=!word:%search%=%replace%!"
echo(!word!
endlocal
)
)
Output of the adapted batch file to the screen:
1 Album 1 - 1982...
2 ('Song 1'),
3 ('Song 2'),
4 |===================|
5 Album 2 - 1978...
6 ('Song 1'),
7 ('Song 2'),
I don't need to change the commas to dots (that was just a test to see if I could make the batch file stop and do something at each instance of a unique string).
My dilemma is that I have searched for hours and can't find how to insert File-2 text in the two proper places of File-1. I've found many explanations on how to insert another file's text at one point or at the end of a first file (using the "type" command), but not at more than one specific point found from the search. Also, File-2 text might be more than two lines in the future, so that is why I want to use an external file to hold it.
All I really want to do right now is:
Find a known string (3 commas).
Read boilerplate text from a text file and insert it below the lines with the found strings, into the the file sitting in the batch file memory.
For testing, I am echoing this to the screen, but once I am able to get the right output, I can edit the batch file to redirect output to a file. I know there are easier ways of doing this using python or C, but it seems it should be easy to do this way with a small correction.
UPDATE
I corrected my batch file per #aschipfl, and made new input files for easier debugging.
a.txt:
A LINE 1,,,
A LINE 2
b.txt:
B LINE 1
B LINE 2
I methodically tried three versions of the FIND statement starting with the #aschipfl original but there is no interaction with b.txt.
if not "!word!"=="!word:%search%=!" find /V ",,," < "!infile2!"
if not "!word!"=="!word:%search%=!" < "!infile2!" find /V ",,,"
if not "!word!"=="!word:%search%=!" find /V ",,," type "!infile2!"
The fourth combination does interact with b.txt as shown below it.
if not "!word!"=="!word:%search%=!" type "!infile2!" find /V ",,,"
C:\Users\Pete\Documents\test>test.bat
A LINE 1,,,
b.txt
B LINE 1
B LINE 2The system cannot find the file specified.
Error occurred while processing: find.
The system cannot find the file specified.
Error occurred while processing: /V.
The system cannot find the file specified.
Error occurred while processing: ,,,.
A LINE 2
C:\Users\Pete\Documents\test>
Now, the batch file reads both lines of both input files but with errors as shown (complete with blank lines, copied directly from screen).
You should not try to replace ,,, by ,,, + line-break + multi-line text from another file, rather should you, after echo(!word!, check whether the current line contains ,,, by if not "!word!"=="!word:,,,=!", and if so, just type out the other text file by type "File-2.txt", or by find /V "" < "File-2.txt" in case its contents may not be terminated with a final line-break:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "infile1=%~dp0File-1.txt"
set "infile2=%~dp0File-2.txt"
set "outfile=con"
set "search=,,,"
> "%outfile%" (
rem // The strange unquoted option string syntax disables the `eol` character:
for /F usebackq^ delims^=^ eol^= %%i in ("%infile1%") do (
set "word=%%i"
setlocal EnableDelayedExpansion
echo(!word!
rem // Try to remove search string; if result differs, search string occurred:
if not "!word!"=="!word:%search%=!" find /V "" < "!infile2!"
endlocal
)
)
endlocal
exit /B
One way to do this in a cmd batch-file would be to use PowerShell. If you are on a supported Windows platform, PowerShell is available. This uses a regex to insert the content of another file.
powershell -NoLogo -NoProfile -Command ^
(Get-Content -Path .\afile1.txt) -replace ',,,', ^
\",,,$([Environment]::NewLine)$(Get-Content -Raw -Path .\afile2.txt)\"
Example:
C:>type afile1.txt
1 Album 1 - 1982,,,
2 ('Song 1'),
3 ('Song 2'),
4 |===================|
5 Album 2 - 1978,,,
6 ('Song 1'),
7 ('Song 2'),
C:>type afile2.txt
NEW LINE 1
NEW LINE 2
C:>powershell -NoLogo -NoProfile -Command ^
More? (Get-Content -Path .\afile1.txt) -replace ',,,', ^
More? \",,,$([Environment]::NewLine)$(Get-Content -Raw -Path .\afile2.txt)\"
1 Album 1 - 1982,,,
NEW LINE 1
NEW LINE 2
2 ('Song 1'),
3 ('Song 2'),
4 |===================|
5 Album 2 - 1978,,,
NEW LINE 1
NEW LINE 2
6 ('Song 1'),
7 ('Song 2'),

How to rename multiple files in bash by moving/replacing characters and converting date format in file name? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
In my log directory I have 600+ log files that have a naming scheme as:
abc.log.DDMMMYYYY
For example:
abc.log.01Nov2017
abc.log.02Nov2017
abc.log.10Dec2017
abc.log.21Jan2018
abc.log.22Jan2018
abc.log.23Jan2018
I am looking a way to rename all these files as...
YYYY-MM-DD.abc.log
The month name in file name must convert to month number. (Jan = 01, Feb = 02 ...)
For example:
2017-11-01.abc.log
2017-11-02.abc.log
2017-12-10.abc.log
2018-01-21.abc.log
2018-01-22.abc.log
2018-01-23.abc.log
How can I rename all these files in bash?
#!/bin/bash -e
# Create kludged associative array (for bash versions prior to 4 -- 4 has
# built-in associative arrays).
i=0
for Month in Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec; do
let i=i+1
# Pad with leading zero and then take last two characters.
Padded=0$i
eval Key$Month=${Padded: -2:2}
done
# Iterate on all files whose names match *.log.*.
for File in *.log.*; do
# Match to pattern with expected date format.
if [[ ! $File =~ ^(.*)\.log\.([0-3][0-9])([A-Z][a-z][a-z])([0-9]{4})$ ]]; then
echo "$File does not match pattern."
else
# Extract matched name and date.
Name=${BASH_REMATCH[1]}
Day=${BASH_REMATCH[2]}
InMonth=${BASH_REMATCH[3]}
Year=${BASH_REMATCH[4]}
# Convert month name abbreviation to month number.
# number %m, day number %d).
eval OutMonth=\$Key$InMonth
NewName="$Year-$OutMonth-$Day.$Name.log"
# Inform user.
echo "Will rename $File to $NewName."
# Rename.
mv "$File" "$NewName"
fi
done
This is locale sensitive, of course. And it expects four-digit dates, so it will break in the year 10,000. And you could add various error checks.
As you have requested batch-file solution, here is a possible solution:
#echo off
setlocal EnableDelayedExpansion
rem Set Month Numbers:
set "Jan=01"
set "Feb=02"
set "Mar=03"
set "Apr=04"
set "May=05"
set "Jun=06"
set "Jul=07"
set "Aug=08"
set "Sep=09"
set "Oct=10"
set "Nov=11"
set "Dec=12"
rem Main Loop to rename files:
for %%A IN (*.log.*) do (
for /f "delims=." %%B IN ("%%~xA") do (
set "extension=%%B"
call ren "%%A" "!extension:~5!-%%!extension:~2,-4!%%-!extension:~0,-7!.abc.log"
)
)
Let me explain break it down:
First we set MMM variables to the requested format: MM.
Now, we come to the main loop.
We loop through all files in the current folder (%cd%) which contain .log.. We do this using * wildcard.
Then, we loop in the extension of each file found.
We set the extension (without the dot (.)) in the variable extension.
After that, we rename file found in first loop (%%A) with the strings found and analyzed.
To better understand how these commands work, I suggest you to open a cmd and type the following commands:
set /?
rem /?
for /?
ren /?
Some interesting references for further reading:
https://ss64.com/nt/for.html
https://ss64.com/nt/ren.html
What does %date:~-4,4%%date:~-10,2%%date:~-7,2%_%time:~0,2%%time:~3,2% mean?
https://www.dostips.com/DtTipsStringManipulation.php#Snippets.MidString
https://www.robvanderwoude.com/battech_wildcards.php
What does "&&" in this batch file?
https://ss64.com/nt/syntax-redirection.html
If gawk is available, please try:
#!/bin/bash
for f in abc.log.*; do echo "$f"; done | awk 'BEGIN {
str="JanFebMarAprMayJunJulAugSepOctNovDec"
for (i=1; i<=12; i++) s2n[substr(str, i*3-2, 3)] = sprintf("%02d", i)
}
{if (match($0, "(.+)\\.([0-9]{2})([A-Z][a-z]{2})([0-9]{4})", a))
printf("%s%c%04d-%02d-%02d.%s%c", $0, 0, a[4], s2n[a[3]], a[2], a[1], 0)
}
' | xargs -0 -n 2 mv
It maps the month name to month number via an array s2n.
The awk script outputs pairs of filenames like: abc.log.01Nov2017, 2017-11-01.abc.log... The filenames are separated by a null character.
The xargs reads the passed filenames two by two and performs mv command on
them.

parsing string in a log file in VBS

I have a windows system logs information to a text file. It is a bat file and records current date, time and result of a cygwin command to a text file.
Current text file is below.
Fri 05/16/2014 16:52:12.19
JAVA_HOME = C:/jdk1.6.0_07
Checking rmi://ppm01:1094/KintanaServer
--> running (load: 343.0, mode: NORMAL)
Checking rmi://ppm02:1197/KintanaServer
--> running (load: 318.0, mode: NORMAL)
Checking rmi://ppm03:1297/KintanaServer
--> running (load: 0.0, mode: NORMAL)
-------------------------------------------
Fri 05/16/2014 16:57:00.03
JAVA_HOME = C:/jdk1.6.0_07
Checking rmi://ppm01:1094/KintanaServer
--> running (load: 334.0, mode: NORMAL)
Checking rmi://ppm02:1197/KintanaServer
--> running (load: 334.0, mode: NORMAL)
Checking rmi://ppm03:1297/KintanaServer
--> running (load: 0.0, mode: NORMAL)
I want to change the text file to
Fri 05/16/2014 16:52:12.19;ppm01;343
Fri 05/16/2014 16:52:12.19;ppm01;318
Fri 05/16/2014 16:52:12.19;ppm03;0
Fri 05/16/2014 16:57:00.03;ppm01;334
Fri 05/16/2014 16:57:00.03;ppm02;334
Fri 05/16/2014 16:57:00.03;ppm02;0
How can I manipulate current text file with VBS to grap the information.
I could not change the command in cygwin also the result of the cygwin command. So what I only could do is changing the already written information.
Here my batch script:
#echo off
C:
cd C:\ppm\bin
echo %date% %time% >> userload_log.txt
C:\cygwin\bin\bash.exe kStatus.sh >> userload_log.txt
For the file format change (batch file, not vbscript)
#echo off
setlocal enableextensions enabledelayedexpansion
set /a "mon=100", "tue=100", "wed=100", "thu=100", "fri=100", "sat=100", "sun=100"
set /a "checking=200", "running=300"
for /f "usebackq tokens=1-8 delims=>-/:. " %%a in ("userload_log.txt") do (
set /a "id=%%a"
if !id! equ 100 (
set "ts=%%a %%b/%%c/%%d %%e:%%f:%%g.%%h;"
) else if !id! equ 200 (
set "ppm=%%c;"
) else if !id! equ 300 (
echo(!ts!!ppm!%%c
)
)
This code tokenizes the lines and uses the first token to determine the information that can be retrieved from it. The rest is saving the adecuated tokens in variables and each time a complete set is retrieved, echo to console the required record
For a VBS version
Option Explicit
Const ForReading = 1
Dim fso
Set fso = WScript.CreateObject("Scripting.FileSystemObject")
Dim inputFile
Set inputFile = fso.OpenTextFile("userload_log.txt", ForReading )
Dim reDate, reChecking, reRunning
Dim inputLine, id, ts, ppm
Do While Not inputFile.AtEndOfStream
inputLine = Trim(inputFile.ReadLine())
If Len(inputLine) > 0 Then
id = split(LCase(inputLine)," ")(0)
Select Case id
Case "mon","tue","wed","thu","fri","sat","sun"
ts = inputLine
Case "checking"
ppm = Split(Mid(inputLine,16),":")(0)
Case "-->"
WScript.StdOut.WriteLine ts & ";" & ppm & ";" & Split(Mid(inputLine,20),".")(0)
End Select
End If
Loop
inputFile.Close()

windows batch file script to sort URLs

How do I write a windows batch script to sort URLs by grouping those with unique file names together in a text file? I don't know how to describe further what I want to achieve but I hope the example below explains everything:
I want this text
http://example.com/5235/Guava.jpg
http://example.com/2725/Guava.jpg
http://example.com/4627/Guava.jpg
http://example.com/8385/Guava.jpg
http://example.com/3886/Lemon.jpg
http://example.com/5896/Lemon.jpg
http://example.com/2788/Lemon.jpg
http://example.com/1758/Lemon.jpg
http://example.com/1788/Apple.jpg
http://example.com/1567/Apple.jpg
http://example.com/8065/Apple.jpg
http://example.com/6467/Apple.jpg
http://example.com/1464/Banana.jpg
http://example.com/6581/Banana.jpg
http://example.com/4642/Banana.jpg
http://example.com/8635/Banana.jpg
http://example.com/2578/Pineapple.jpg
http://example.com/1452/Pineapple.jpg
http://example.com/8652/Pineapple.jpg
http://example.com/9463/Pineapple.jpg
http://example.com/9765/Peach.jpg
http://example.com/3578/Peach.jpg
http://example.com/3583/Peach.jpg
http://example.com/9467/Peach.jpg
http://example.com/3683/Mango.jpg
http://example.com/3479/Mango.jpg
http://example.com/1795/Mango.jpg
http://example.com/7345/Mango.jpg
sorted this way
http://example.com/5235/Guava.jpg
http://example.com/3886/Lemon.jpg
http://example.com/1788/Apple.jpg
http://example.com/1464/Banana.jpg
http://example.com/2578/Pineapple.jpg
http://example.com/9765/Peach.jpg
http://example.com/3683/Mango.jpg
http://example.com/2725/Guava.jpg
http://example.com/5896/Lemon.jpg
http://example.com/1567/Apple.jpg
http://example.com/6581/Banana.jpg
http://example.com/1452/Pineapple.jpg
http://example.com/3578/Peach.jpg
http://example.com/3479/Mango.jpg
http://example.com/4627/Guava.jpg
http://example.com/2788/Lemon.jpg
http://example.com/8065/Apple.jpg
http://example.com/4642/Banana.jpg
http://example.com/8652/Pineapple.jpg
http://example.com/3583/Peach.jpg
http://example.com/1795/Mango.jpg
http://example.com/8385/Guava.jpg
http://example.com/1758/Lemon.jpg
http://example.com/6467/Apple.jpg
http://example.com/8635/Banana.jpg
http://example.com/9463/Pineapple.jpg
http://example.com/9467/Peach.jpg
http://example.com/7345/Mango.jpg
In other words, for this particular example (withe four of each fruit jpeg) I want to sort lines according to this manner: 1, 5, 9, 13, 17, 21, 25, 2, 6, 10, 14, 18, 22, 26, and so on. I hope you get what I mean.
The text file always contains urls with the same number of every "fruit" picture. There can't be six lemon jpg files and four guava jpg files. I hope you get what I what I mean.
Maybe something like this:
#ECHO OFF
SET origfile=urls.txt
SET c=1
SET skip=4
FOR /L %%c IN (1,1,%skip%) DO IF EXIST %origfile%.%%c DEL %origfile%.%%c
FOR /F "tokens=*" %%L IN (%origfile%) DO CALL :process "%%L"
DEL %origfile%
FOR /L %%c IN (1,1,%skip%) DO (
TYPE %origfile%.%%c >> %origfile%
DEL %origfile%.%%c
)
GOTO :EOF
:process
ECHO %~1>>%origfile%.%c%
SET /A c=c%%skip+1
The idea is to output subsequent lines to different files, repeating the sequence every 4 lines (and 4 is parametrised here actually, so you can easily change it), then concatenate those files under the original name.
Run this on your file. Algorithm as described in my comment above.
#!/bin/bash
FILE=$1
FIRST=$(head -1 $FILE)
COUNT=$(grep $FIRST $FILE | wc -l)
LINES=$(uniq $FILE)
for i in $(seq 1 $COUNT); do
echo $LINES | tr " " "\n"
done
You can tell sort where to start comparing:
/+n Specifies the character number, n, to
begin each comparison. /+3 indicates that
each comparison should begin at the 3rd
character in each line. Lines with fewer
than n characters collate before other lines.
By default comparisons start at the first
So if your URI prefix is always the same (which your comments indicated) you can just run the file through
sort /+25 list.txt /O:list_new.txt
which should sort it by file name, then.

A library for creating .TMB images?

Is anyone aware of a library suitable for writing an image in .TMB format?
The .TMB format is suitable for printing logos from a Epson thermal receipt printer.
After about an hour or so of looking at binary data, I came to the following conclusion:
A *.TMB image is really just a serialized ESC/POS command to print a raster image.
Using the following command:
od -t a -v [YOUR_TMB_FILE] | head
we can view the binary data, as ASCII character data, in the beginning of the TMB file.
I had a file that looked something like this:
0000000 gs v 0 nul 5 nul P nul del del del del del del del del
0000020 del del del del del del del del del del del del del del del del
... snipped for brevity ...
According to the ESC/POS Programming Guide, the ASCII command to print a raster image is:
GS V 0
Hmm.. Interesting!
On a whim, I decided to convert 5 and P to their decimal equivalents, which are 53 and 80 respectively, the exact dimensions of my .TMB image (actually, its 80x53)!
Everything fell into place after this. The remainder of a .TMB file is just the binary image data.
Here is a one-off Python script I wrote to test my theory:
1 out = open('test.TMB', 'wb')
2
3 width = 80
4 height = 53
5
6 NUL = chr(0)
7 GS = chr(29)
8 V = chr(118)
9 ZERO = chr(48)
10
11 W = chr(width)
12 H = chr(height)
13
14 out.write(GS)
15 out.write(V)
16 out.write(ZERO)
17 out.write(NUL)
18
19 out.write(H)
20 out.write(NUL)
21 out.write(W)
22 out.write(NUL)
23
24 for y in range(0, height):
25 for x in range(0, width):
26 out.write(chr(127)) # looks like `del` in ASCII mode
27
28 out.close()

Resources