How to do it in PowerShell? Or: which language to use for processing files and strings?

What language should I use to process files and strings?

It may seem objective, but I really don't think so. There you can say that. For example, I clearly see that for most applications, Perl would be a more obvious candidate than Java. I need to do this quite often, and at this time I use C # for this, but for this I would like to use a more scripting language.

I can imagine that Perl would be a candidate for this, but I would like to do it in PowerShell since PowerShell can access the .NET library (easily). Or is Python better suited for this? If I need to learn a new language, Python is definitely one on my list, not Perl.

What I want to do, for example, is to read the file, make some changes and save it again. For example: open it, enter all the lines (say 3 digits) and close it. Any example, in any language, is welcome, but the shorter the better. These are utility scripts that I am here, not OO, TDDeveloped, tested for testing, of course.

What I would love to see is something like ( pseudocode here):

open foobar.as f foreach line in f.lines line.addBefore(currenIteratorCounter.format('ddd') + '. ') close f 

So:

 bar.txt Frank Zappa Cowboy Henk Tom Waits numberLines bar.txt bar.txt 001. Frank Zappa 002. Cowboy Henk 003. Tom Waits 

UPDATE:

The Perl and Python examples here are great and definitely match what I hoped and expected. But are there any PowerShell supporters?

+4
source share
6 answers

This is actually pretty easy in PowerShell :

 function Number-Lines($name) { Get-Content $name | ForEach-Object { $i = 1 } { "{0:000}. {1}" -f $i++,$_ } } 

What I'm doing here is getting the contents of the file, this will return a String[] , over which I repeat with ForEach-Object and apply the format string using the -f operator. The result simply drops out of the pipeline as another String[] , which can be redirected to the file if necessary.

You can shorten it a bit by using aliases:

 gc .\someFile.txt | %{$i=1}{ "{0:000}. {1}" -f $i++,$_ } 

but I will not recommend this for function definition.

You want to consider using two passes, although constructing an on-the-fly format string to accommodate more lines. If there are 1500 lines {0:000} , then it will not be enough to get a neatly aligned output.

As for the language that is best suited for such tasks, you can look at factors such as

  • brevity of code (Perl will be hard to beat there, especially that one-line in another answer)
  • readability and maintainability of the code
  • Accessibility tools (Perl and Python are not installed by default on Windows (PowerShell only with Windows 7), so deployment can be difficult.)

In light of the last point, you might even be better off using cmd for this task. The code is similarly pretty simple:

 @echo off setlocal set line=1 for /f "delims=" %%l in (%1) do call :process %%l endlocal goto :eof :process call :lz %line% echo %lz%. %* set /a line+=1 goto :eof :lz if %1 LSS 10 set lz=00%1&goto :eof if %1 LSS 100 set lz=0%1&goto :eof set lz=%1&goto :eof goto :eof 

This suggests, of course, that it should work somewhere else than your own machine. If not, use whatever suits you :-)

+11
source
 perl -i -ne 'printf("00%d. %s",$.,$_)' your-filename-here 

Instead, you might want% 03d.

+2
source

This is not what you wanted, but please remember findstr.exe (and find.exe) from time to time ...

findstr / n ". *" filename find "" / v / n filename

+2
source

Python

 target = open( "bar_with_numbers.txt", "w" ) source = open( "bar.txt", "r" ) for count, line in enumerate( source ): target.write( "%3d. %s\n" % ( count+1, line ) ) source.close() target.close() 

Firstly, this is a bad policy for "updating" files. This ultimately becomes a regrettable decision because debugging is complicated by the loss of history.

If you use the OS redirection functions, this program can be simplified.

 import sys for count, line in enumerate( sys.stdin ): sys.stdout.write( "%3d. %s\n" % ( count+1, line ) ) 

Then you can run this enumerate.py as follows

 python enumerate.py <bar.txt >bar_with_numbers.txt 

More importantly, you can also do this.

 python enumerate.py <bar.txt | the_next_step 
+1
source

Definitely Perl. It supports built-in replacements (on Windows you must run the script with perl.i.bak (because Windows cannot do this inline and creates a .bak file with the same name.)

 open(IN,'+>'.$yourfile) || die "Can not open file $yourfile: $!"; my $line_no = 1; while(<IN>){ print "$line_no. $_"; $line_no++; } close IN; 

Code simply printed from memory without testing. But that should work. You probably want to add some logic to format $ line_no (for example, the first lines of the count, and then add as many zero digits as you need.)

+1
source

On a Debian system (and possibly other Linux distributions) you can do this:

 $ nl -w 3 -n rz -s ". " [filename] > [newfilename] 
+1
source

Source: https://habr.com/ru/post/1286189/


All Articles