Remove multiple empty lines from text file - windows

I have a text file where data is something like this,
Hosts
-------------
host id | hostname
------------------+-------------------------------------------
651 | host1
652 | host2
Guests
------------
guest id | guestname
------------------+-----------
61 | guest1
I need to remove the 2 empty lines but leave the single empty lines to differentiate. Tried below for loop but that deletes all the records.
for /f "usebackq tokens=* delims=" %%a in ("test.txt") do (echo(%%a)>>~.txt
move /y ~.txt "test.txt"
The expected result is like below
Hosts
-------------
host id | hostname
------------------+-------------------------------------------
651 | host1
652 | host2
Guests
------------
guest id | guestname
------------------+-----------
61 | guest1

You could utilise the findstr command which supports a tiny subset of regular expressions:
In Command Prompt:
>>> for %L in (^"^
...
... ^") do #for /F %C in ('copy /Z "%ComSpec%" nul') do #findstr /V /R /C:"^ *%~C%~L *%~C%~L.*|.*$" /C:"^ *%~C%~L.*|.*$" "test.txt"
In a batch script:
#echo off
for %%L in (^"^
%= blank line =%
^") do (
for /F %%C in ('copy /Z "%ComSpec%" nul') do (
findstr /V /R /C:"^ *%%~C%%~L *%%~C%%~L.*|.*$" /C:"^ *%%~C%%~L.*|.*$" "test.txt"
)
)
This code assumes that the text file contains DOS/Windows-style line-breaks consisting of a carriage-return (CR, ASCII 0x0D) and a line-feed (LF, ASCII 0x0A) character.

Related

combine all txt file in a folder

I want to combine all the txt files having a header in a folder. I need the header to be written only once.
s1.txt
Header
1
2
3
4
5
6
7
8
s2.txt
Header
12
22
32
42
52
62
72
82
s3.txt
Header
123
223
323
423
523
623
723
823
There are two solutions
1: Simple one
copy /b *.txt Combined.txt // It writes header each time also
2: solution with loop
#echo off
for %%f in (*.txt) do (
if not exist Combined.txt (
copy "%%f" Combined.txt
) else (
for /F "usebackq skip=1 delims=" %%a in ("%%f") do (
echo %%a>> Combined.txt
)
)
)
But it is not working properly.
Header
1
2
3
4
5
6
7
812 // NEED to start with next line
22
32
42
52
62
72
82
123
223
323
423
523
623
723
823
Any idea?? Also other solutions???
A quite simple solution is to use the find command since this appends a final line-break when needed, so you do not have to particularly take care of that on your own:
#echo off
rem /* Use a flag-style variable that indicates the first file,
rem so we know whether or not we have to apply the header: */
set "FIRST=#"
rem // Write to the output file:
> "Combined.txt" (
rem /* Loop through all input files, with the order is defined by the file system
rem (the used pattern also ensures to does not match the output file): */
for %%I in ("s*.txt") do (
rem // Query the flag-style variable:
if defined FIRST (
rem // This is the first input file, hence return the whole content:
< "%%~I" find /V ""
) else (
rem // This is not the first input file, hence exclude the header:
< "%%~I" find /V "Header"
)
rem // Clear the flag-style variable here:
set "FIRST="
)
)
If the header string (Header) may occur within other lines but the headline also, try to replace the command line < "%%~I" find /V "Header" by the one < "%%~I" (set /P ="" & findstr "^"), although this might cause problems on certain Windows versions as findstr might hang (refer to the post What are the undocumented features and limitations of the Windows FINDSTR command?).
Here is an approach based on for /F loops; the difference to your similar approach is that also the first file is handled by a for /F loop, which lets also the last line be terminated by a line-break in the output:
#echo off
rem /* Use a flag-style variable that indicates the first file,
rem so we know whether or not we have to apply the header: */
set "FIRST=#"
rem // Write to the output file:
> "Combined.txt" (
rem /* Loop through all input files, with the order is defined by the file system
rem (the used pattern also ensures to does not match the output file): */
for %%I in ("s*.txt") do (
rem // Query the flag-style variable:
if defined FIRST (
rem // This is the first input file, hence return the whole content:
for /F "usebackq delims=" %%L in ("%%~I") do (
echo(%%L
)
) else (
rem // This is not the first input file, hence exclude the header:
for /F "usebackq skip=1 delims=" %%L in ("%%~I") do (
echo(%%L
)
)
rem // Clear the flag-style variable here:
set "FIRST="
)
)
Note that a for /F skips blank lines.
This code assumes that the header is in the first file mentioned. If you are on a supported Windows machine, PowerShell will be available. This may require the current PowerShell 5.1 or higher.
=== Get-CombinedFile.ps1
$outFilename = 'C:/src/t/Combined.txt'
$files = #('./s1.txt', './s2.txt', './s3.txt')
Set-Location -Path 'C:/src/t'
Get-Content -Path $files[0] -First 1 |
Out-File -FilePath $outFilename -Encoding ascii
Get-ChildItem -Path $files |
ForEach-Object {
Get-Content -Path $_ |
Select-Object -Skip 1 |
Out-File -FilePath $outFilename -Encoding ascii -Append
}
Invoke it in a cmd.exe shell or .bat file script.
powershell -NoLogo -NoProfile -File 'C:\src\t\Get-CombinedFile.ps1'

wmic useraccount SID blank spaces/empty lines

I have this two commands to get SID useraccount
wmic useraccount where name='%username%' get sid | findstr /b /C:"S-1" > file.txt
or
for /F "tokens=2 delims=," %f in ('whoami /user /FO CSV /NH') do echo %~f > file.txt
both cases (file.txt) contain blank spaces/empty lines. I try to remove with
findstr /r /v "^$"
But it is impossible. How can remove all blank spaces/empty lines to get only SID number
#echo off
setlocal enableextensions disabledelayedexpansion
for /f "skip=2 tokens=2 delims=," %%a in ('
wmic path win32_useraccount
where name^="%username%"
get sid^,status /format:csv
') do (
>"file.txt" <nul set /p"=%%a"
)
That will skip headers, include an additional field so the sid is the second field in the record (in csv format the node field gets included) so we can avoid an ending carriage return in the output of the wmic command (each line ends in CR+CR+LF) and the output is sent to the file using a set /p command with the input stream reading from nul device. This way the output to the file will not include the ending CR+LF that is included with echo
The same code for in the whoami version
#echo off
setlocal enableextensions disabledelayedexpansion
for /f "tokens=2 delims=," %%a in ('
whoami /user /FO CSV /NH
') do (
>"file.txt" <nul set /p"=%%~a"
)
This batch file can did the trick :
#echo off
for /f "delims= " %%a in ('"wmic path win32_useraccount where name='%UserName%' get sid"') do (
if not "%%a"=="SID" (
set myvar=%%a
goto :loop_end
)
)
:loop_end
echo SID=%myvar%
echo %myvar% > SID_%username%.txt
pause>nul
Start "" SID_%username%.txt
For the second method of whoami /user /FO CSV /NH ,you can take a look at this :
Get SID for current logged in domain user
Here's how I'd do it, WMIC:
for /f "skip=1" %a in ('"wmic useraccount where name='%username%' get sid"') do #for %b in (%a) do #(>file.txt echo(%b)
and with WhoAmI
for /f tokens^=3^ delims^=^" %a in ('whoami /user /FO CSV /NH') do #(>file.txt echo(%a)
both in the command line to match the question (ignoring the batch-file tag).

echo %DATE% output

When i run my below batch script, I received an error
Invalid switch - /d:"
Can someone please help me with this?
My batch file script to copy file:
#ECHO OFF
FOR /F "tokens=2 delims= " %%V IN ("%DATE%") DO SET TDY=%%V
xcopy /y "\\page1\page\*.*" "D:\Users\kskkuga\Desktop\day\*.*" /d:%TDY%
SET TDY=
#pause
Try for example in explorer to rename a folder with date formatted like this dd/mm/yyyy
You getting this error because you are trying to create/rename a file with slash "/" separator.
You need to parse the date with the right delims and tokens.
The delims here is / and tokens 1,2,3 or 1-3 (meaning 1 to 3)
Edit: your date format show Fri 25/09/2015 so I updated the table representation, tokens and delims in batch script.
Fri d d / m m / y y y y
1 | 2 | 3 | 4
| %%a | %%b | %%c
_____|_____|_____|________
here you go.
#echo off
setlocal
for /f "tokens=2,3,4 delims=/ " %%a in ('echo %date%') do set tdy=%%c%%b%%a
xcopy /y "\\page1\page\*.*" "d:\users\kskkuga\desktop\day\" /d:%tdy%
exit /b 0
Resource you must read:
for /?
xcopy /?
http://ss64.com/nt/xcopy.html

Echo the contents of a paragraph into a file without any modifications to the paragraph?

How do i echo a paragraph into a file without doing any kind of manipulation to the paragraph.
i mean newline,space,special characters etc and all the indentation should be same.
My .bat file(containing the contents of .ppk file)
echo (PuTTY-User-Key-File-2: ssh-rsa
Encryption: none
Comment: rsa-key-20130127
Public-Lines: 6
AAAAB3NzaC1yc2EAAAABJQAAAQBVYEVYbGluh1Ne6psUMsK4TRiqwN8GG+ImbsfC
qIYje3S7n3owtEUSDMEc5VvTZTEXk/CKHK6tXhGSNrExXKDhKE2HejY7TFtbc3vU
KM4OogxYeZs/0yBX/kVEu5+kIeZ0ZEsq/ve9/hnEVLZ3DFotUoDzzwdd4jAHUZv2
08xk5tTxodh+iO26RVPSaklZrFjbZkqCwPOnVZhK6JqE/7kZyIM+p5W8CH8XPG3r
fgU/R4BpwMNz+pYo2iiV3eZApI25lY+IcjclA5Amx1JdCM1zIvA6C8ABUbTMXsyG
RHkzdEYjw5+pBF8qLU8s8+M9sw0l5z58dP9t+vuYWz+JrsmL
Private-Lines: 14
AAABAECb4XNY9dcaTO3h+NED0aA6V9sqLDv5bN7QX9GUSdWpiMVWF0dzqeQlU96E
DiNvLBHXvPLlRer7FDdL+7am9kmGSIIy+JuTusG/LUaba4Cx+4E5bpEqJlBtZNoR
ceP9+oGYAYhSPvCkneCuz0VVdKytI1C4WJoS8+nc5LrJyxvsFGgVEIo5nadkABRV
eOLwotq2Mj/lLXHMbE5lB+9m9VNsWrBErNVCwNQdhQOyG1E39YcwBV+hB+Pyu41z
6EHxIRXQvbYNE2HjLvowrnX/9fFfx1kf51+WE+VbFQxrrZqE1p3y2S2kJkAopRio
KZBlNwrR6mwSLtRn4a6ZecKwVE0AAACBAJVV6O5leR0gl27DVqnXu6mhf6Xb8Ije
2JfvLCa73bgpFSYQ2EpxKTiSpZpM3kPpnC7Y0SvigstGHwze/OuCXYnzT/KDkBrs
NDPiuTSmzW3JxtGv1axpfRRt/PaRIHq6pCtyGxIc5A0RrTuSrPzZkHxFggkAYSMK
9YOi1sZhcVtlAAAAgQCSW1Pvq4zSjsUuGMc/w8T8mOOZG4Yllq7e9CSpTMeqeVHl
Vytm5+ujIyas/k/UGA8WQt3ZnD5uLF7tBRoaHf88oE00nXVnLlDeME3Jdbts84tE
1HB9RzwGE+BVknEiNcUjqhVcRqv6+pOClR+K5VOstqs/tmmMOA57c1481K/aLwAA
AIAQn9Fhg4Ih71uvber4RELcZCQrvRFsuASYHrgYBkzw17PTPQ9APv0B1nIPZ/u6
+jhou7qzR78yrYw0Po4ZJmmDt0CP/cZPWL4jQ6sM6on98D6TdKk7rE1c0WPn1Bta
ZtaxQqOku7eAfw745L9EjokekZjohjTFI9rSFdsCfa6dXw==
Private-MAC: 2e75877ab827b492b2a0a16c5019cd45f96e4990) > myfile.txt
The above line does not work after i save it as .bat and execute
i want to put the paragraph in a file with a unique name so that it does not overwrite any existing file.
Do i need to echo at each and every line and keep appending.
Put a unique text marker after the final EXIT /B, followed by your paragraph. Use FOR /F with FINDSTR to locate the unique marker, and then use a FOR /F loop to process all the lines after the marker.
There are many variations, each with different limitations.
Here is the simplest form, but it also has the most limitations. The limitations are described in the text.
#echo off
setlocal disableDelayedExpansion
set "skip="
for /f "delims=:" %%N in (
'findstr /x /n ":::BeginText" "%~f0"'
) do if not defined skip set skip=%%N
>test.txt (
for /f "usebackq skip=%skip% delims=" %%A in ("%~f0") do echo(%%A
)
type test.txt
exit /b
:::BeginText
This text will be exactly preserved with the following limitations:
1) Each line will be terminated by CR LF even if original has only LF.
2) Lines are limited in length to approximately 8191 bytes.
3) Empty lines will be stripped.
; 4) Lines beginning with ; will be stripped.
5) The text will be truncated at the first occurance of hex code 0x1A (Ctrl-Z).
Special characters like ^ & < > | etc. do not cause a problem
Some odd FOR /F option syntax removes the limitation on lines beginning with ;
#echo off
setlocal disableDelayedExpansion
set "skip="
for /f "delims=:" %%N in (
'findstr /x /n ":::BeginText" "%~f0"'
) do if not defined skip set skip=%%N
>test.txt (
for /f ^usebackq^ skip^=%skip%^ delims^=^ eol^= %%A in ("%~f0") do echo(%%A
)
type test.txt
exit /b
:::BeginText
This text will be exactly preserved with the following limitations:
1) Each line will be terminated by CR LF even if original has only LF.
2) Lines are limited in length to approximately 8191 bytes.
3) Empty lines will be stripped.
4) The text will be truncated at the first occurance of hex code 0x1A (Ctrl-Z).
Special characters like ^ & < > | etc. do not cause a problem
;Lines beginning with ; are preserved
Reading FINDSTR /N output instead of reading the file directly preserves empty lines. But a new limitation with leading : is introduced.
#echo off
setlocal disableDelayedExpansion
set "skip="
for /f "delims=:" %%N in (
'findstr /x /n ":::BeginText" "%~f0"'
) do if not defined skip set skip=%%N
>test.txt (
for /f "skip=%skip% tokens=1* delims=:" %%A in (
'findstr /n "^" "%~f0"'
) do echo(%%B
)
type test.txt
exit /b
:::BeginText
This text will be exactly preserved with the following limitations:
1) Each line will be terminated by CR LF even if original has only LF.
2) Lines are limited in length to approximately 8191 bytes.
::: 3) Leading : will be stripped from each line.
Special characters like ^ & < > | etc. do not cause a problem
Empty lines are preserved!
;Lines beginning with ; are preserved.
This final version is about as good as it gets. Delayed expansion must be toggled on and off to preserve ! that may appear in the text.
#echo off
setlocal disableDelayedExpansion
set "skip="
for /f "delims=:" %%N in (
'findstr /x /n ":::BeginText" "%~f0"'
) do if not defined skip set skip=%%N
>test.txt (
for /f "skip=%skip% tokens=*" %%A in (
'findstr /n "^" "%~f0"'
) do (
set "line=%%A"
setlocal enableDelayedExpansion
echo(!line:*:=!
endlocal
)
)
type test.txt
exit /b
:::BeginText
This text will be exactly preserved with the following limitations:
1) Each line will be terminated by CR LF even if original has only LF.
2) Lines are limited in length to approximately 8191 bytes.
Special characters like ^ & < > | etc. do not cause a problem.
Empty lines are preserved!
;Lines beginning with ; are preserved.
:::Leading : are preserved.

MS DOS 'for' command to access file contents -- spaces

If a.txt contains
a b c
abc
The command for /f %x in (a.txt) do echo %x is printing
a
abc
What am I doing wrong?
for /f "tokens=*" %x in (a.txt) do #echo %x
The #echo will prevent the echo line from being printed
for /f "delims=|" %i in (a.txt) do #echo %i
Inside "delims=|" you can use any character for the delimiter that is not part of the file
#echo off
setlocal
for /F "usebackq tokens=1-3 delims= " %%a IN ("a.txt") DO (
if not "%%a"=="" echo.%%a
if not "%%b"=="" echo.%%b
if not "%%c"=="" echo.%%c
)
Tokens - the set of chars delimited by one of the delim char.
You can specify many delim chars, i.e. delims= .,

Resources