win cmd: remove whitespace > not enough storage to process this command - windows

I have a long (several million lines) data sheet in plain txt. Looks like this:
cellnumber x-coordinate y-coordinate z-coordinate temperature
1 -6.383637190E-01 2.408539131E-02 -5.244855285E-01 3.081549136E+02
2 -6.390314698E-01 2.286404185E-02 -5.245100260E-01 3.081547595E+02
3 -6.381718516E-01 2.373264730E-02 -5.236577392E-01 3.081547591E+02
4 -6.360489130E-01 2.259869128E-02 -5.245736241E-01 3.081547591E+02
5 -6.369081736E-01 2.253472991E-02 -5.236831307E-01 3.081547591E+02
6 -6.382256746E-01 2.215057984E-02 -5.237988830E-01 3.081547591E+02
7 -6.381900311E-01 2.126700431E-02 -5.245448947E-01 3.081547591E+02
8 -6.373924613E-01 2.117809094E-02 -5.238834023E-01 3.081547591E+02
I currently only have win command line and need to get rid off the whitespaces ath the beginning (their length is not constant as the cellnumber increases) so that I get
cellnumber x-coordinate y-coordinate z-coordinate temperature
1 -6.383637190E-01 2.408539131E-02 -5.244855285E-01 3.081549136E+02
2 -6.390314698E-01 2.286404185E-02 -5.245100260E-01 3.081547595E+02
3 -6.381718516E-01 2.373264730E-02 -5.236577392E-01 3.081547591E+02
4 -6.360489130E-01 2.259869128E-02 -5.245736241E-01 3.081547591E+02
5 -6.369081736E-01 2.253472991E-02 -5.236831307E-01 3.081547591E+02
6 -6.382256746E-01 2.215057984E-02 -5.237988830E-01 3.081547591E+02
7 -6.381900311E-01 2.126700431E-02 -5.245448947E-01 3.081547591E+02
8 -6.373924613E-01 2.117809094E-02 -5.238834023E-01 3.081547591E+02
May I ask for a solution? I dont have a clue, am not really experienced with this. Thx!
I guess TrimStart may be my friend.
EDIT: I have put together this:
#ECHO OFF
set "victim=testJana.txt"
SETLOCAL
FOR /F "tokens=*" %%A IN (%victim%) DO (
IF NOT "%%A"=="_" ECHO %%A>>%victim%_edited.txt
)
ENDLOCAL
pause
it works fine for smaller files but Im getting the message
not enough storage to process this command
Any idea how to deal with this?

I would suggest using powershell:
First, Second and Third edit: To be executed in the directory where data.txt file is placed and in the powershell.exe shell:
(good point to add -ReadCount by #lit in other post)
Get-Content -ReadCount 500 -Path .\path_to_your_source\data.txt | % {$_ -replace " +", " "} | Set-Content -Path .\path_to_our_output\data_no_additional_spaces.txt
Why -ReadCount makes sense? Here it takes 500 lines per run via pipes.
Here is the info from Microsoft pages)
-ReadCount
Specifies how many lines of content are sent through the pipeline at a
time. The default value is 1. A value of 0 (zero) sends all of the
content at one time.
This parameter does not change the content displayed, but it does
affect the time it takes to display the content. As the value of
ReadCount increases, the time it takes to return the first line
increases, but the total time for the operation decreases. This can
make a perceptible difference in very large items.
Reads data, replaces all the spaces and then saves data into data_new.txt
This answer was meant for the powershell.exe shell not the cmd.exe where you normally run your *.bat files. In powershell you have scripts called *.ps1.
If you store this the above command in a trim_space.ps1 and then launch it as (you need to have the script in the same directory as the data being transformed):
powershell.exe -ExecutionPolicy Bypass &'C:\path_to_script\trim_space.ps1'. You will see it executed.
Forth edit
To address your:
it works fine for smaller files but Im getting the message not enough
storage to process this command
Any idea how to deal with this?
You have to process it by chunks which you are not doing in your batch file right now. You get just to the point where you exhaust all the thread memory and it naturally fails. You need to have approach which allows you to limit the chunk of lines which are processed at once like -Readcount. In batch file I imagine it would be possible to call one batch file from other which would process only limited part of the file.

Using PowerShell, you can limit how much data is processed at a time in the pipeline.
Get-Content -Path .\testJana.txt -ReadCount 1000 |
ForEach-Object { $_ -replace '^ +', '' } |
Out-File -FilePath .\testJana_edited.txt -Encoding ASCII
If you want to run this from a cmd.exe shell, put the PowerShell code above into a file named sourcelimit.ps1 and use the following in a .bat script file.
powershell -NoProfile -File .\sourcelimit.ps1

Related

cmd dir write file size in windows 10 in Gb instead of byte [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 3 years ago.
Improve this question
I use command
dir L01\*.gz /o-s/-c > L01.txt
to find all gz files in directory and sort by size. It works well!
But, I need to take size in Gb not in bytes!
01/24/2020 12:36 AM 3018394731 v3000418221_L01_82_1.fq.gz
01/24/2020 12:36 AM 2883376937 v3000418221_L01_82_2.fq.gz
01/24/2020 12:36 AM 2875257587 v3000418221_L01_69_1.fq.gz
01/24/2020 12:36 AM 2785098410 v3000418221_L01_69_2.fq.gz
01/24/2020 12:36 AM 2520038171 v3000418221_L01_99_1.fq.gz
01/24/2020 12:36 AM 2478618550 v3000418221_L01_62_1.fq.gz
01/24/2020 12:36 AM 2470651439 v3000418221_L01_99_2.fq.gz
also I need only filenames and sizes in Gb without date and time
And, it will be great if command do it with files in all subdirectures and give output like:
directory L01 (or smth else):
v3000418221_L01_82_1.fq.gz 2.5 Gb
v3000418221_L01_82_2.fq.gz 2.4 Gb
directory L02 :
v3000418221_L01_12_1.fq.gz 2.1 Gb
v3000418221_L01_32_2.fq.gz 0.4 Gb
v3000418221_L01_42_1.fq.gz 1.5 Gb
v3000418221_L01_8_2.fq.gz 2.4 Gb
It is not my computer so I try to do it in cmd without installing python.
You can do the following in PowerShell to search the current directory, which will output FileInfo objects sorted by Length (Size) and with size converted to GB.
Output to Console Only
Get-ChildItem -Filter '*L01*.gz' | Sort Length -Desc |
Select LastWriteTime,Name,#{n='SizeGB';e={$_.Length/1GB}}
If you want set the directory within the command, you can add -Path DirectoryPath to your Get-ChildItem command. The -Recurse switch allows for a recursive directory search from the search directory. See Get-ChildItem.
If you want the pipe the output to a file as is, you can just add | Out-File L01.txt or | Set-Content L01.txt.
In PowerShell, dir is an alias for Get-ChildItem. So you can use dir -Filter '*L01*.gz' if you feel the need.
Output to File Without Table Headers
PowerShell works with objects. If your objects have property names, they will by default appear as column headers in a table output. If you want the headers removed, you can just pipe your output to Format-Table -HideTableHeaders.
Get-ChildItem -Filter '*L01*.gz' | Sort Length -Desc |
Select LastWriteTime,Name,#{n='SizeGB';e={$_.Length/1GB}} |
Format-Table -HideTableHeaders | Set-Content L01.txt
Output to File From CMD Shell
If you only want to run code from the cmd shell, then you can still execute the PowerShell code there. Just put the PowerShell code in a script file Something.ps1.
Powershell.exe -File Something.ps1
There are some differences in default encoding for Out-File and Set-Content. In Windows PowerShell > redirects output (can target a file or stream) and uses Unicode with BOM. Out-File behaves the same as the redirect operator when no parameters are supplied. In PowerShell Core or just PowerShell (as of v7), both commands should output to files by default in UTF-8 with no BOM. Set-Content outputs using the culture-specific Default encoding. Both commands have an -Encoding parameter for you to control your output encoding.

How to use the fast ping with alot of ip addressess in cmd to send alot of packets for every hop?

What have I tried
I wanted to create a way to make a faster pinging method for cmd than the normal '-t' command. So I came up with an idea to make two files and link them together:
The first st1.bat file contains
ping 10.10.10.10 -n 1
st2.bat
And the second st2.bat file contains
ping 10.10.10.10 -n 1
st1.bat
This creates a loop so it goes on forever.
The '-n' command is the number of packets you send. So by sending just one packet and then opening the second .bat file makes it a lot faster (30 milliseconds).
The command for extracting just the IP addresses is:
(#for /f "tokens=8" %a in ('tracert -4 -d wikipedia.org^|find "ms"') do #echo start ping %a)>ips.txt
What do I need
I want to combine these two codes and make 2 files for each IP to create a loop just like I showed you above. Every IP loop should have its own cmd window because if everything is in one window every packet should wait for the previous one to be done:
And finally link all the files together in one .bat file that I think will look like that:
Start st1.bat
Start st3.bat
Start st5.bat
Try to use: ping -n 1 -l 1
if you doesn't want
Firing with 1 bytes of data: try this command:
#echo off
:1
ping -n 1 -l 1 | find "TLL="
goto 1

Move columns in CSV with batch or powershell

I'm using MediaInfo CLI version in Win 7 x64 to automatically make a CSV via template when a video file has finished encoding in StaxRip.
However, its CLI version is critical about how to apply the output template (long story short, its variables are in sections (general, video, audio, text) and you can only use one section in one block, you can't go back to a previous section further down the template), so one variable that I want elsewhere has to end up in the wrong spot for the automation to even work.
Like this:
UTC 2015-05-21 18:04:06,Episode01.mp4,211 MiB,22mn 7s,29.970 fps,1 210 Kbps,High 10#L3,120 Kbps,AAC,Japanese
UTC 2015-05-21 19:16:18,Episode02.mp4,211 MiB,22mn 6s,29.970 fps,1 212 Kbps,High 10#L3,118 Kbps,AAC,Japanese
UTC 2015-05-21 20:24:57,Episode03.mp4,211 MiB,22mn 6s,29.970 fps,1 212 Kbps,High 10#L3,119 Kbps,AAC,Japanese
What I'm looking for is the timestamp portion (first column) to become the LAST column instead:
Episode01.mp4,211 MiB,22mn 7s,29.970 fps,1 210 Kbps,High 10#L3,120 Kbps,AAC,Japanese,UTC 2015-05-21 18:04:06
I would very much love to find a solution to this in a .bat or Powershell script if possible since these are already used in the aforementioned process, but am open to small single-purpose applications. The crucial part is being able to be run from CMD or from a master .bat file.
Thank you for your time.
I tried this one out and is working.
[string] $SourceFileFullPath = "C:\Projects\INT\CSV_ColumnSwap.csv"
[Array] $SourceFileContent = Get-Content $SourceFileFullPath
[int] $ArrayLength = $SourceFileContent.length
for ($i=0; $i -lt $ArrayLength; $i++) {
$splitter1 = ","
$LineData = $SourceFileContent[$i] -split $splitter1
$DateTimeV, $Linedata = $LineData
$LineData += $DateTimeV
$LineData -join "," >> Result.csv
}
I am not particularly sure about the performance aspects. YMMV.
Cheers

Extract hostnames from Perfmon blg with Powershell

I'm writing a script which will automate the extraction of data from .blg Perfmon logs.
I've worked out the primary Import-Counter commands I will need to use to get the data out, but am trying to parametrise this so that I can do it for each machine in the log file (without having to open the log up in Perfmon, which can take 15 minutes or sometimes more, and is the reason I'm writing this script), and find out what each hostname is.
The script I have does the job, but it still takes a minute to return the data I want, and I wondered if there was a simpler way to do this, as I'm not too familiar with Powershell?
Here's what I have:
$counters = Import-Counter -Path $log_path$logfile -ListSet * | Select-Object paths -ExpandProperty paths
$svrs = #()
# for each line in the list of counters, extract the name of the server and add it to the array
foreach ($line in $counters) {
$svrs += $line.split("\")[2]
}
# remove duplicates and sort the list of servers
$sorted_svrs = $svrs | sort -unique
foreach ($svr in $sorted_svrs) {
Write-Host $svr
}
I'm just printing the names for the moment, but they'll go into an array in the proper script, and then I'll run my Import-Counter block with each of these hosts parametrised in.
Just wondered if there was a better way of doing this?
$sorted_svrs=Import-Counter "$log_path$logfile" -Counter "\\*\physicaldisk(_total)\% disk time" | %{$_.countersamples.path.split("\")[2]} | sort -Unique

Unix tail equivalent command in Windows Powershell

I have to look at the last few lines of a large file (typical size is 500MB-2GB). I am looking for a equivalent of Unix command tail for Windows Powershell. A few alternatives available on are,
http://tailforwin32.sourceforge.net/
and
Get-Content [filename] | Select-Object -Last 10
For me, it is not allowed to use the first alternative, and the second alternative is slow. Does anyone know of an efficient implementation of tail for PowerShell.
Use the -wait parameter with Get-Content, which displays lines as they are added to the file. This feature was present in PowerShell v1, but for some reason not documented well in v2.
Here is an example
Get-Content -Path "C:\scripts\test.txt" -Wait
Once you run this, update and save the file and you will see the changes on the console.
For completeness I'll mention that Powershell 3.0 now has a -Tail flag on Get-Content
Get-Content ./log.log -Tail 10
gets the last 10 lines of the file
Get-Content ./log.log -Wait -Tail 10
gets the last 10 lines of the file and waits for more
Also, for those *nix users, note that most systems alias cat to Get-Content, so this usually works
cat ./log.log -Tail 10
As of PowerShell version 3.0, the Get-Content cmdlet has a -Tail parameter that should help. See the technet library online help for Get-Content.
I used some of the answers given here but just a heads up that
Get-Content -Path Yourfile.log -Tail 30 -Wait
will chew up memory after awhile. A colleague left such a "tail" up over the last day and it went up to 800 MB. I don't know if Unix tail behaves the same way (but I doubt it). So it's fine to use for short term applications, but be careful with it.
PowerShell Community Extensions (PSCX) provides the Get-FileTail cmdlet. It looks like a suitable solution for the task. Note: I did not try it with extremely large files but the description says it efficiently tails the contents and it is designed for large log files.
NAME
Get-FileTail
SYNOPSIS
PSCX Cmdlet: Tails the contents of a file - optionally waiting on new content.
SYNTAX
Get-FileTail [-Path] <String[]> [-Count <Int32>] [-Encoding <EncodingParameter>] [-LineTerminator <String>] [-Wait] [<CommonParameters>]
Get-FileTail [-LiteralPath] <String[]> [-Count <Int32>] [-Encoding <EncodingParameter>] [-LineTerminator <String>] [-Wait] [<CommonParameters>]
DESCRIPTION
This implentation efficiently tails the cotents of a file by reading lines from the end rather then processing the entire file. This behavior is crucial for ef
ficiently tailing large log files and large log files over a network. You can also specify the Wait parameter to have the cmdlet wait and display new content
as it is written to the file. Use Ctrl+C to break out of the wait loop. Note that if an encoding is not specified, the cmdlet will attempt to auto-detect the
encoding by reading the first character from the file. If no character haven't been written to the file yet, the cmdlet will default to using Unicode encoding
. You can override this behavior by explicitly specifying the encoding via the Encoding parameter.
Probably too late for an answere but, try this one
Get-Content <filename> -tail <number of items wanted> -wait
Just some additions to previous answers. There are aliases defined for Get-Content, for example if you are used to UNIX you might like cat, and there are also type and gc. So instead of
Get-Content -Path <Path> -Wait -Tail 10
you can write
# Print whole file and wait for appended lines and print them
cat <Path> -Wait
# Print last 10 lines and wait for appended lines and print them
cat <Path> -Tail 10 -Wait
I have a useful tip on this subject concerning multiple files.
Following a single log file (like 'tail -f' in Linux) with PowerShell 5.2 (Win7 and Win10) is easy (just use "Get-Content MyFile -Tail 1 -Wait"). However, watching MULTIPLE log files at once seems complicated. With PowerShell 7.x+ however, I've found an easy way by using "Foreach-Object -Parrallel". This performs multiple 'Get-Content' commands concurrently. For example:
Get-ChildItem C:\logs\*.log | Foreach-Object -Parallel { Get-Content $_ -Tail 1 -Wait }
Using Powershell V2 and below, get-content reads the entire file, so it was of no use to me. The following code works for what I needed, though there are likely some issues with character encodings. This is effectively tail -f, but it could be easily modified to get the last x bytes, or last x lines if you want to search backwards for line breaks.
$filename = "\wherever\your\file\is.txt"
$reader = new-object System.IO.StreamReader(New-Object IO.FileStream($filename, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [IO.FileShare]::ReadWrite))
#start at the end of the file
$lastMaxOffset = $reader.BaseStream.Length
while ($true)
{
Start-Sleep -m 100
#if the file size has not changed, idle
if ($reader.BaseStream.Length -eq $lastMaxOffset) {
continue;
}
#seek to the last max offset
$reader.BaseStream.Seek($lastMaxOffset, [System.IO.SeekOrigin]::Begin) | out-null
#read out of the file until the EOF
$line = ""
while (($line = $reader.ReadLine()) -ne $null) {
write-output $line
}
#update the last max offset
$lastMaxOffset = $reader.BaseStream.Position
}
I found most of the code to do this here.
I took #hajamie's solution and wrapped it up into a slightly more convenient script wrapper.
I added an option to start from an offset before the end of the file, so you can use the tail-like functionality of reading a certain amount from the end of the file. Note the offset is in bytes, not lines.
There's also an option to continue waiting for more content.
Examples (assuming you save this as TailFile.ps1):
.\TailFile.ps1 -File .\path\to\myfile.log -InitialOffset 1000000
.\TailFile.ps1 -File .\path\to\myfile.log -InitialOffset 1000000 -Follow:$true
.\TailFile.ps1 -File .\path\to\myfile.log -Follow:$true
And here is the script itself...
param (
[Parameter(Mandatory=$true,HelpMessage="Enter the path to a file to tail")][string]$File = "",
[Parameter(Mandatory=$true,HelpMessage="Enter the number of bytes from the end of the file")][int]$InitialOffset = 10248,
[Parameter(Mandatory=$false,HelpMessage="Continuing monitoring the file for new additions?")][boolean]$Follow = $false
)
$ci = get-childitem $File
$fullName = $ci.FullName
$reader = new-object System.IO.StreamReader(New-Object IO.FileStream($fullName, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Read, [IO.FileShare]::ReadWrite))
#start at the end of the file
$lastMaxOffset = $reader.BaseStream.Length - $InitialOffset
while ($true)
{
#if the file size has not changed, idle
if ($reader.BaseStream.Length -ge $lastMaxOffset) {
#seek to the last max offset
$reader.BaseStream.Seek($lastMaxOffset, [System.IO.SeekOrigin]::Begin) | out-null
#read out of the file until the EOF
$line = ""
while (($line = $reader.ReadLine()) -ne $null) {
write-output $line
}
#update the last max offset
$lastMaxOffset = $reader.BaseStream.Position
}
if($Follow){
Start-Sleep -m 100
} else {
break;
}
}
try Windows Server 2003 Resource Kit Tools
it contains a tail.exe which can be run on Windows system.
https://www.microsoft.com/en-us/download/details.aspx?id=17657
There have been many valid answers, however, none of them has the same syntax as tail in linux. The following function can be stored in your $Home\Documents\PowerShell\Microsoft.PowerShell_profile.ps1 for persistency (see powershell profiles documentation for more details).
This allows you to call...
tail server.log
tail -n 5 server.log
tail -f server.log
tail -Follow -Lines 5 -Path server.log
which comes quite close to the linux syntax.
function tail {
<#
.SYNOPSIS
Get the last n lines of a text file.
.PARAMETER Follow
output appended data as the file grows
.PARAMETER Lines
output the last N lines (default: 10)
.PARAMETER Path
path to the text file
.INPUTS
System.Int
IO.FileInfo
.OUTPUTS
System.String
.EXAMPLE
PS> tail c:\server.log
.EXAMPLE
PS> tail -f -n 20 c:\server.log
#>
[CmdletBinding()]
[OutputType('System.String')]
Param(
[Alias("f")]
[parameter(Mandatory=$false)]
[switch]$Follow,
[Alias("n")]
[parameter(Mandatory=$false)]
[Int]$Lines = 10,
[parameter(Mandatory=$true, Position=5)]
[ValidateNotNullOrEmpty()]
[IO.FileInfo]$Path
)
if ($Follow)
{
Get-Content -Path $Path -Tail $Lines -Wait
}
else
{
Get-Content -Path $Path -Tail $Lines
}
}
Very basic, but does what you need without any addon modules or PS version requirements:
while ($true) {Clear-Host; gc E:\test.txt | select -last 3; sleep 2 }
It is possible to download all of the UNIX commands compiled for Windows from this GitHub repository: https://github.com/George-Ogden/UNIX
For those admins who live by the axiom that less typing is best, here is the shortest version I can find:
gc filename -wai -ta 10

Resources