1..500 | ?{ !(Test-Path ('{0:0000}_A.csv' -f $_)) }
Explanation:1..500 generates a sequence of numbers 1 through 500
| pipes the numbers
?{ … } is a filter that is evaluated for each item (number)
! negates the following expression
Test-Path tests that a file exists
-f formats the string left of -f with the parameters (zero-based to the right of -f
'{0:0000}_A.csv' is a pattern which formats parameter 0 as 4 digits, zero-padded.
EDIT: Explanation
for f in {0001..0500}_A.csv; do test -e $f || echo $f; doneIt is a Python implementation of this idea: OS objects like files and processes are represented in Python. You construct pipelines as in UNIX, but passing Python objects instead of strings. E.g. to find the pids of /bin/bash commands:
osh ps ^ select 'p: p.commandline.startswith("/bin/bash")' ^ f 'p: p.pid' $
- osh: Runs the tool, interpreting the rest of the line as an osh command.- ^: Piping syntax.
- ps: Generate a stream of process objects, (the currently running processes).
- select: Select those processes, p, whose commandline starts with /bin/bash.
- f: Apply the function to the input stream and write function output to the output stream, (so, basically "map"). The function computes the pid of an input process.
- $ Print each item received in the input stream.
Osh also does database access (query results -> python tuples) and remote access. E.g., to get a process listing of (pid, commandline) on every node in a cluster:
osh @clustername [ ps ^ f 'p: (p.pid, p.commandline)' ] $ pgrep -f /bin/bash osh timer 1 ^ \
f 't: (t, processes())' ^ \
expand 1 ^
f 't, p: (p.pid, int(t), p.commandline)' ^
sql "insert into process values(%s, %s, %s)"
- timer 1: Generate a timestamp every second.- f 't: (t, processes())': Take the timestamp as input and generate a timestamp and sequence of Process objects.
- expand 1: Expand the sequence of Processes, so that there is one per output tuple, e.g. (123, (p1, p2)) -> (123, p1), (123, p2).
- f 't, p: (p.pid, int(t), p.commandline)': Take the timestamp and Process as input, and generate (pid, timestamp as int, command line) as output.
- sql "insert into process values(%s, %s, %s)": Take the triples from the previous command and dump them into a table in a database.
But dont say powershell is not practical for simple things. Its very practical for simple and complex things. And I am productive with it.
If you do a lot of work with Exchange though, you'll probably end up using PowerShell much more, because the web UI for it is not so great.
No matter what you think of the specific implementation, a lot of PowerShell's ideas are good ideas. Unfortunately UNIX culture is such that they'll probably never implement any of them.
ssh, docker, ansible, kubernetes, grafana, prometheus, etc... All coming from Linux/unix. This statement is clueless. Most of the cloud is not running microsoft, and for a good reason.
To automate, we have python, which has a much better syntax. It's pointless to use powershell.
And it takes a microsoft head, without knowledge of programming language's history to say that powershell's ideas actually come from powershell. Method chaining/fluent interface with a pipe instead of a dot does not look that new.
Also, some attempts have been to implement posh clones on unix. Being redundant with either perl/python or bash/zsh, none succeeded.
I would like to see more work done in the realm of object shells (and have some ideas myself), especially around designs that meld in more the UNIXy way of having independent communicating processes. But it is a difficult problem domain, and many approaches would involve rewriting lot of the base system we take for granted that is just huge amount of work.
PowerShell had the benefit of having stuff like WMI, COM, the whole .NET, and of course all the resources, funding and marketing from MS. Even then it has seemed to have been an uphill struggle, despite there being far more a need for PS in the Windows world.
With regard to the 'ints' it helps to not think about them as ints but rather just some text that follows the pattern ^[0][1-9] or some equivalent to that. "Starts with any number of zeros or no zeros followed by any number of numbers between 1 to 9 or none at all."
So long as you know the repeatable pattern you can always use sed to just replace the part of the pattern you want gone with nothing which effectively deletes it from the output. sed is like a Swiss army knife in that regard because you can do nice simple deletions like that and even iterate on them if you need or you can do quite complicated capture groups if you need to as well. Sed can get you unbelievably far in terms of shaping text in a stream.
I have a few tricks I've learned with various tools that I thought were worth writing down. Hopefully you can find some more useful stuff.
https://github.com/nicostouch/grep-sed-awk-magic/blob/master...
^[0]*[0-9]+$
to avoid matching empty lines? ^[0]*[1-9]*
You could use + if you want. I only do it if not doing will produce incorrect output for my given input, which happens occasionally but is rare.Bear in mind in this case there is also _A.csv or _B.csv you need to account for as well which your version doesn't. Mine will still pick it up because I'm not specifying the end, as I'm assuming I've done the necessary preprocessing steps to get good data so it will produce the expected output.
I'm not usually fussed on being that strict when I write regex as I tend to do various preprocessing steps like grep -v ^$ to filter out any blank lines if I don't want them in the stream etc.
$ seq -w 0001 0005|numfmt
1
2
3
4
5
Or just use plain sed: $ seq -w 0001 0005|sed 's/^0*//'
1
2
3
4
5