Salisbury Giant and HobnobThis page is my attempt at creating a Powershell version of Peter Krumins’ ‘Perl One-Liners Explained‘.

This isn’t necessarily a natural use of Powershell – you can get stuff to work, but it’s not really playing to Powershell’s strengths. Having said which, it’s a fun and useful learning exercise.

Peter has written 3 ‘one-liner’ books:

I bought the ‘sed’ one and it’s very good indeed. Peter explains all of the commands really clearly. I haven’t really attempted to do that here, as yet. Anyway Peter kindly agreed that I could use his headings and try to replicate his one-liners.

As you’ll notice some of my ‘one-liners’ spread over more than one line, and some are only kept to one-line with a liberal use of the ‘;’.

However, I think they are all sets of commands I could envisage typing in at the command line. Perhaps they would be more properly called ‘powershell command-liners‘ rather than ‘powershell one-liners‘.

The usual caveats to code from the internet apply here, but more so. 90% of these snippets were created in the odd spare few minutes, or sat in front of the telly, or while I was waiting for something to run. If I was going to rely on anything here, I’d test it rigourously. You should too.

[toc]

File Spacing

Double space a file

foreach ($LINE in $(gc c:henry8.txt)) {write-host $LINE ; write-host}

This isn’t the best code in the world. It’s not really a one-liner, strictly speaking. As in DOS, I think’ the ‘;’ means treat the following code as if it’s on a new line. In terms of being a one-liner it’s cheating.

A better scripted version

If this was in a script I would code it as follows:

foreach ($LINE in $(gc c:henry8.txt))
{
  write-host $LINE
  write-host
}

This is much easier to read in a script, or on a blog page. It would be easier to debug and to maintain.

So, why a one-liner?

….but there is some value in the original way I’ve written it, all scrunched up on one line. It’s the way I typically would write it at the command line.

I could certainly use carriage-returns at the command line and type it in as I have in the second code piece, but I prefer not to for a couple of reasons.

First, the one-liner shows up better in the command line history[1]. The one-liner below is Id 9, the multi-liner is Id 7

PS C:UsersMatt> history 7,9

  Id CommandLine
  -- -----------
   7 foreach ($LINE in $(gc henry8.txt)) ...
   9 foreach ($LINE in $(gc henry8.txt)) {write-host $LINE ; write-host}

Second, one-liners make it easier to use up-arrow at the command line. You just have to up-arrow once then edit the line and hit return.

Another alternative

Anyway, a slightly improvement on the above is this

foreach ($LINE in $(gc henry8.txt)) {$LINE  + "`n"}

This is arguably a proper ‘one-liner’ in that I haven’t used a semi-colon. It concatenates a new-line character onto the end of each retrieved line instead. This might be seen as more elegant, but it involves typing a backtick so I don’t know.

Double space a file, except the blank lines

foreach ($LINE in $(gc c:henry8.txt)) {write-host $LINE ; if ("$LINE" -ne "") {write-host} }

This depends on the line being totally blank.

Triple space a file

foreach ($LINE in $(gc c:henry8.txt)) {write-host $LINE ; write-host; write-host}

N-space a file

$n = 3
foreach ($LINE in $(gc c:henry8.txt)) {write-host $LINE ; if ("$LINE" -ne "") {for ($i = 0; $i -lt $n ; $i++) { write-host} } }

Add a blank line before every line

foreach ($LINE in $(gc c:henry8.txt)) {write-host ; write-host $LINE}

Remove all blank lines

foreach ($LINE in $(gc c:henry8.txt)) { if ("$LINE" -ne "") {write-host $LINE} }

or

select-string -notmatch "^$" -path c:henry8.txt

The latter here is, as you would expect, much more efficient.

Running

measure-command {select-string -notmatch "^$" -path c:henry8.txt} | select totalmilliseconds

…and

measure-command {foreach ($LINE in $(gc c:henry8.txt)) { if ("$LINE" -ne "") {write-host $LINE} } } | select totalmilliseconds

….shows the former taking less than 1 ms and the latter taking about 87 ms

Remove all consecutive blank lines, leaving just one

foreach ($LINE in $(gc c:henry8.txt))  {  if ("$LINE$LAST_LINE" -ne "") {write-host $LINE} ; $LAST_LINE = $LINE }

<?php /*

Compress/expand all blank lines into N consecutive ones

 

*/ ?>
<?php /*

Fold a file so that every set of 10 lines becomes one tab-separated line


*/?>

Remove all spacing between words

foreach ($LINE in $(gc c:henry8.txt)) { $LINE -replace " ", "" }

Change all spacing between words to one space

foreach ($LINE in $(gc c:henry8.txt)) { $LINE -replace "  *", " " }

Insert a space between all characters

This one certainly needs some work. It’s many lines, it doesn’t honour the carriage returns and it’s generally a bit rubbish. Having said all of which, it does insert a space between all the characters.

$SPACED_LINE = ""
foreach ($LINE in $(gc henry8.txt))
{
  foreach ($C in $LINE.tochararray())
    {
      $SPACED_LINE = "$SPACED_LINE $C "
  }
}
$SPACED_LINE

Line Numbering

Number all lines in a file

PS>select-string ^  c:henry8.txt   | select LineNumber, Line | ft -a

<?php /*

Number only non-empty lines in a file


*/?>

Number and print only non-empty lines in a file (drop empty lines)

$ArrayOfNonBlankLines = select-string -notmatch ^$ c:henry8.txt | select Line
$NumberOfLines = $ArrayOfNonBlankLines.length - 1
foreach ($COUNT in 1..$NumberOfLines ) {write-host $COUNT $ArrayOfNonBlankLines[$COUNT -1].Line }

There are probably various ways of doing this. What I’ve done here is as follows:

Read all the lines into an array but filter out lines which are blank using ‘-notmatch ^$’. The ‘^$’ literally means ‘start-of-line-character immediately followed by end-of-line-character’. So I’m only really filtering out lines which are totally blank i.e. no spaces, no tabs, no nothing

$ArrayOfNonBlankLines = select-string -notmatch ^$ c:henry8.txt | select Line

Count the number of lines for use in a for-loop. The ‘-1’ is there because the first line will be line 0 (or I guess ‘element 0’) in the array

$NumberOfLines = $ArrayOfNonBlankLines.length - 1

Loop through the array, printing out the count, followed by the line itself. The ‘1..$NumberOfLines’ construct just means ‘for 1 to whatever number $NumberOfLines is’. ‘1..5’ would iterate 5 times.

foreach ($COUNT in 1..$NumberOfLines ) {write-host $COUNT $ArrayOfNonBlankLines[$COUNT -1].Line }

<?php /*

Number all lines but print line numbers only non-empty lines


*/?>
<?php /*

Number only lines that match a pattern, print others unmodified


*/?>
<?php /*

Number and print only lines that match a pattern


*/?>
<?php /*

Number all lines, but print line numbers only for lines that match a pattern


*/?>
<?php /*

Number all lines in a file using a custom format (emulate cat -n)


*/?>

Print the total number of lines in a file (emulate wc -l)

gc c:henry8.txt | measure-object | select count

Print the number of non-empty lines in a file

gc c:henry8.txt | measure-object -line -word -character

Print the number of empty lines in a file

select-string ^$ c:henry8.txt | measure-object

Print the number of lines in a file that match a pattern (emulate grep -c)

select-string grease c:henry8.txt | measure-object

Number words across all lines

gc c:henry8.txt | measure-object -line -word -character

Number words on each individual line

foreach ($LINE in $(gc c:henry8.txt)) {$Count = $LINE.split(" ").length - 1 ; "$Count $Line" }

So this gives:

15 But the King himself was left for death by a Greater King, and the earth
8 was to be rid of him at last.
0
14 He was now a swollen, hideous spectacle, with a great hole in his leg,
13 and so odious to every sense that it was dreadful to approach him. When

The elements of this are as follows.

For every line in the text file…

foreach ($LINE in $(gc c:henry8.txt))

…split the line into separate words, and then count the words (by using the .length method) and take off 1 (see note below)

                                       {$Count = $LINE.split(" ").length - 1  }

…then output the count followed by the line itself

                                                                                 "$Count $Line"

To be honest, I can’t quite see why I need the ‘-1’.

If I do:

"X Y Z".split().length

… I get 3, which is what I would expect. Perhaps when reading from a file it treats the carriage return as a separate word. I dunno….it’s late.

<?php /*

Replace all words with their numeric positions

*/?>

Calculations

Check if a number is a prime

$ANumber=312
foreach ($PossDenominator in 2..($ANumber -1))
{
  if ($ANumber%$PossDenominator -eq 0) {"$Anumber is Divisble by $PossDenominator"}
}

If nothing is returned the number is a prime.

Print the sum of all the fields on a line

foreach ($LINE in $(gc c:numbers.txt)) {$NUMBERS = $LINE.split() ; $SUM = 0 ; foreach ($N in $NUMBERS) {$SUM = $SUM + $N} ; write -host $SUM }

Print the sum of all the fields on all lines

$SUM = 0 ; foreach ($LINE in $(gc c:numbers.txt)) {$NUMBERS = $LINE.split() ; $SUM = 0 ; foreach ($N in $NUMBERS) {$SUM = $SUM + $N}  } ; write-host $SUM

<?php /*

Shuffle all fields on a line

*/?>

Find the minimum element on a line

foreach ($LINE in $(gc c:numbers.txt))
{
  write-host "Line is $LINE"
  $NUMBERS = $LINE.split()
  [double]$MIN = 999999999999999999999999999999
  foreach ($N in $NUMBERS)
  {
    if ([double]$N -lt $MIN)
    {
      $MIN = $N
    }
  }
  write-host "Min is $MIN "
}

This didn’t work without casting the numerics as [double].
<?php /*

Find the minimum element over all the lines


*/?>
<?php /*

Find the maximum element on a line


*/?>
<?php /*

Find the maximum element over all the lines


*/?>
<?php /*

Replace each field with its absolute value


*/?>

Find the total number of fields (words) on each line

foreach ($LINE in $(gc henry8.txt)) { $WORDS = $LINE.split() ; $WORDS.length  }

Print the total number of fields (words) on each line followed by the line

foreach ($LINE in $(gc henry8.txt)) { $WORDS = $LINE.split() ; $WORDS.length.tostring() + " $LINE"  }

<?php /*

Find the total number of fields (words) on all lines


*/?>
<?php /*

Print the total number of fields that match a pattern


*/?>

Print the total number of lines that match a pattern

I’m using a file which has a lot of dates in it – it’s a version of a this page from my Salisbury local history website. So I’m using this pattern to look for years which are in the 19th and 20th century: 1[89][0-9][0-9].

So:

select-string 1[89][0-9][0-9] henry8.txt | measure-object | select count

Print the number PI to n decimal places

$n=4
"{0:F$n}" -f [math]::PI

However it seems that Pi is only calculated to 14 decimal places:

PS>[math]::pi
3.14159265358979
PS>"{0:F18}" -f [math]::PI
3.141592653589790000

Props to:
The Scripting Guy

Print the number PI to 39 decimal places

I’m not sure you can do this in native Powershell. At least not without much better Powershell or mathematical skills than I’ve got.

it seems that Pi is only calculated to 14 decimal places:

PS>[math]::pi
3.14159265358979
PS>"{0:F18}" -f [math]::PI
3.141592653589790000

<?php /*

Print the number E to n decimal places


*/?>
<?php /*

Print the number E to 39 decimal places


*/?>

Print UNIX time (seconds since Jan 1, 1970, 00:00:00 UTC)

get-date -UFormat "%s"

The ‘U’ is for Unix 🙂

…and the Help says:

s   Seconds elapsed since January 1, 1970 00:00:00 (1150451174.95705)

Print GMT (Greenwich Mean Time) and local computer time

(get-date).ToUniversalTime()
get-date

I’m not entirely sure that the former is right. I have the great good fortune to have been born in England, so I can’t easily test whether the two commands return different things.

Print local computer time in H:M:S format

get-date -Uformat %T

Print yesterday’s date

$(get-date).adddays(-1)

Print date 14 months, 9 days and 7 seconds ago

$(get-date).adddays(-14).addmonths(-9).addseconds(-7)

<?php /*

Prepend timestamps to stdout (GMT, localtime)


*/?>

Calculate factorial of 5

$n = 5
$ArrayOfNumbers = 2..$n
$Factorial = 1
foreach ($N in $ArrayOfNumbers) {$Factorial = $Factorial * $N ; $Factorial}

<?php /*

Calculate greatest common divisor (GCM)


*/?>
<?php /*

Calculate GCM of numbers 20 and 35 using Euclid’s algorithm


*/?>
<?php /*

Calculate least common multiple (LCM) of numbers 35, 20 and 8


*/?>
<?php /*

Calculate LCM of 20 and 35 using Euclid’s formula: n*m/gcd(n,m)


*/?>

Generate 10 random numbers between 5 and 15 (excluding 15)

get-random -minimum 5 -maximum 15

According to the Powershell help the -maximum parameter:

Specifies a maximum value for the random number. Get-Random returns a value that is less than the maximum (not equal).

To be honest this doesn’t entirely match mu understanding of the word maximum. I would take ‘maximum’ to be inclusive. i.e. if a taxi holds a maximum of 5 passengers, then it can take 5 people but not 6. Powershell is taking ‘maximum’ to be exclusive, i.e.

foreach ($n in 1..5) {$(get-random -min 5 -max 6)}

gives

5
5
5
5
5

I’m sure this says more about my use of English than it does about Powershell!
<?php /*

Find and print all permutations of a list


*/?>
<?php /*

Generate the power set


*/?>
<?php /*

Convert an IP address to unsigned integer


*/?>
<?php /*

Convert an unsigned integer to an IP address


*/?>

String creation and array creation

Generate and print the alphabet

foreach ($n in 97..122) {"$([char]$n)"}

This uses the [char]number construct. If you do [char]number, you get the character represented by the number as an ascii value. So char[97] returns ‘a’, char[98] returns ‘b’ and so on

If you wanted the alphabet all in one string you could do this:

$Alphabet
foreach ($n in 97..122) { $Alphabet=$Alphabet+$([char]$n) }
$Alphabet

<?php /*

Generate and print all the strings from “a” to “zz”


*/?>

Create a hex lookup table

foreach ($N in 1..100) {"$N " + [Convert]::ToString($N, 16)}

I found out how to convert to and from hex at Michael Flanakin’s blog

<?php /*

Convert a decimal number to hex using @hex lookup table


*/?>

Generate a random 8 character password

$PW=""
foreach ($n in 1..8)
{
  $CHAR = [char][int]$(get-random -min 32 -max 126)
  $PW = $PW + $CHAR
  $PW
}

This also uses the [char]number construct, as in the ‘Generate and print the alphabet’ one-liner above. If you do [char]number, you get the ascii value for the number, so char[97] returns ‘a’, char[98] returns ‘b’ and so on.

Here I’m using get-random to return random printable characters. The printable characters are from ascii 32 to ascii 126.

<?php /*

Create a string of specific length


*/?>
<?php /*

Create a repeated list of elements


*/?>

Create an array from a string

"Google paid £6m tax on £395m revenue".tochararray()

If you wanted to store the array in a variable, then:

$ArrayFromString = "Google paid £6m tax on £395m revenue".tochararray()

Create a string from an array

foreach ($C in $ArrayFromString) {$StringBackFromArray = $StringBackFromArray + $C}
$StringBackFromArray

Find the numeric values for characters in the string

foreach ($N in "Tax-dodgers rob soldiers and doctors and teachers".tochararray()) {[int][char]$N}

Convert a list of numeric ASCII values into a string

foreach ($N in (103,111,111,103,108,101,32,100,111,100,103,101,32,116,97,120,101,115)) {$String = $String + [char]$N }

Generate an array with odd numbers from 1 to 100

$ArrayOfOddNumbers = for ($i = 1; $i -lt 100 ; $i=$i+2) {$I}
$ArrayOfOddNumbers

Generate an array with even numbers from 1 to 100

$ArrayOfEvenNumbers = for ($i = 0; $i -lt 101 ; $i=$i+2) {$I}
$ArrayOfEvenNumbers

Find the length of the string

"Google paid £6m tax on £395m revenue" | select length

Find the number of elements in an array

$ArrayFromString.length -1

Text conversion and substitution

<?php /*

ROT13 a string


*/?>
<?php /*

ROT 13 a file


*/?>
<?php /*

Base64 encode a string


*/?>
<?php /*

Base64 decode a string


*/?>
<?php /*

URL-escape a string


*/?>
<?php /*

URL-unescape a string


*/?>
<?php /*

HTML-encode a string


*/?>
<?php /*

HTML-decode a string


*/?>

Convert all text to uppercase

"Google paid £6m tax on £395m revenue".ToUpper()

I found that running a get-member on any string is a handy quick reference for Powershell string functions (technically they are methods not functions, I guess)

So

"Google paid £6m tax on £395m revenue" | gm

…gives you a handy list:

Name
----
Clone
CompareTo
Contains
CopyTo
EndsWith
Equals
GetEnumerator
GetHashCode
GetType
GetTypeCode
IndexOf
IndexOfAny
Insert
IsNormalized
LastIndexOf
LastIndexOfAny
Normalize
PadLeft
PadRight
Remove
Replace
Split
StartsWith
Substring
ToBoolean
ToByte
ToChar
ToCharArray
ToDateTime
ToDecimal
ToDouble
ToInt16
ToInt32
ToInt64
ToLower
ToLowerInvariant
ToSByte
ToSingle
ToString
ToType
ToUInt16
ToUInt32
ToUInt64
ToUpper
ToUpperInvariant
Trim
TrimEnd
TrimStart
Chars
Length

Convert all text to lowercase

"Google paid £6m tax on £395m revenue".Tolower()

Uppercase only the first word of each line

foreach ($LINE in $(gc c:henry8.txt)) {
  $First = $LINE.split()[0]
  $Rest = $LINE.trim($First)
  $First.ToUpper() + $Rest
}

<?php /*

Invert the letter case


*/?>
<?php /*

Camel case each line


*/?>

Strip leading whitespace (spaces, tabs) from the beginning of each line

"          Google paid £6m tax on £395m revenue           ".TrimStart()

Not sure this works with tabs
<?php /*

Strip trailing whitespace (space, tabs) from the end of each line

"Google paid £6m tax on £395m revenue           ".TrimEnd() | select length

Can prove this is working by doing this:

"Google paid £6m tax on £395m revenue           " | select length
"Google paid £6m tax on £395m revenue           ".TrimEnd() | select length

Strip whitespace from the beginning and end of each line

"     Google paid £6m tax on £395m revenue           ".trim()

….seems to work

Incidentally, this will take the ‘e’ off the end:

"Google paid £6m tax on £395m revenue".trim("e")

And it works with words too:

"Dont Be Evil".trim("Dont ")

<?php /*

Convert UNIX newlines to DOS/Windows newlines


*/?>
<?php /*

Convert DOS/Windows newlines to UNIX newlines


*/?>
<?php /*

Convert UNIX newlines to Mac newlines


*/?>

Substitute (find and replace) “foo” with “bar” on each line

(Get-Content C:henry8.txt) | Foreach-Object {$_ -replace "Henry", "Horrible"}

<?php /*

Substitute (find and replace) all “foo”s with “bar” on each line


*/?>
<?php /*

Substitute (find and replace) “foo” with “bar” on lines that match “baz”


*/?>
<?php /*

Binary patch a file (find and replace a given array of bytes as hex numbers)


*/?>

Selective printing and deleting of certain lines

Print the first line of a file (emulate head -1)

gc henry8.txt | select-object -first 1

Print the first 10 lines of a file (emulate head -10)

gc henry8.txt | select-object -first 10

Print the last line of a file (emulate tail -1)

gc henry8.txt | select-object -last 1

Print the last 10 lines of a file (emulate tail -10)

gc henry8.txt | select-object -last 10

Print only lines that match a regular expression

select-string "ff*i" henry8.txt

Print only lines that do not match a regular expression

select-string -notmatch "ff*i" henry8.txt

Print the line before a line that matches a regular expression

$f = select-string  -context 2,0 "ff*ian" henry8.txt
$f[0].context.precontext | select-object -last 1

Not entirely sure how this is working tbh, I cobbled it together from the help.

The key learning for me was that when you use the -context switch, you don’t generate more rows as such – the context lines are part of the same logical row, even though they look like extra rows when they come back to the screen.

Print the line after a line that matches a regular expression

$f = select-string  -context 0,1 "ff*ian" henry8.txt
$f[0].context.postcontext | select-object -first 1

<?php /*

Print lines that match regex AAA and regex BBB in any order


*/?>
<?php /*

Print lines that don’t match match regexes AAA and BBB


*/?>
<?php /*

Print lines that match regex AAA followed by regex BBB followed by CCC


*/?>
<?php /*

Print lines that are 80 chars or longer


*/?>
<?php /*

Print lines that are less than 80 chars in length


*/?>

Print only line 13

gc henry8.txt | select-object -index 13

<?php /*

Print all lines except line 27


*/?>

Print only lines 13, 19 and 67

gc henry8.txt | select-object -index 13,19,67

Whichever order you put the index numbers in, it will still come out in the order of the input
<?php /*

Print all lines between two regexes (including lines that match regex)


*/?>

Print all lines from line 17 to line 30

$a = 13..17
gc henry8.txt | select-object -index $a

<?php /*

Print the longest line


*/?>

Print the shortest line

This works, more or less…

$FileContents = gc henry8.txt
$ShortestLine = $FileContents | select-object -first 1

foreach ($LINE in $FileContents)
{
  write-host "Line is $LINE"
  if ($LINE.length -lt $ShortestLine.length -and $LINE -ne "" )
  {
      $ShortestLine = $LINE
  }
  write-host "Shortest line is $ShortestLine"
}

In Powershell terms this is fairly straightfowrward:

Read the contents of the file into a Powershell variable

$FileContents = gc henry8.txt

Initialize the variable $ShortestLine to the first line. I could have used any line here – it’s just a start point for comparison

$ShortestLine = $FileContents | select-object -first 1

Loops through the contents of the file

foreach ($LINE in $FileContents) 
{

Just writing out the contents so I’ve got something to look at. In ‘real life’ this would be write-verbose or write-debug

  write-host "Line is $LINE"

Compare the line length with whatever was previously saved as the shortest. I’m filtering out totally blank lines.

  if ($LINE.length -lt $ShortestLine.length -and $LINE -ne "" )
  { 

If its is the shortest line, save it into the $ShortestLine variable

      $ShortestLine = $LINE
  } 

Report back what the shortest line is

  write-host "Shortest line is $ShortestLine"
}

In ‘real life’ you might want to filter out lines that consist of just spaces or just tabs too.

<?php /*

Print all lines that contain a number


*/?>
<?php /*

Find all lines that contain only a number


*/?>
<?php /*

Print all lines that contain only characters


*/?>
<?php /*

Print every second line


*/?>
<?php /*

Print every second line, starting the second line


*/?>
<?php /*

Print all lines that repeat


*/?>

Print all unique lines

gc henry8.txt | Group-Object {$_}  | select name

I think this works. There’s a get-unique cmdlet in Powershell, but that only works on pre-sorted lists and only filters consecutive duplicates.

Group-object seems to preserver the order of the first occurrence of a particular line.

Group-object itself is a bit like the SQL ‘GROUP BY’. A more ‘natural’ use of Group-Object would be:

get-process | group-object {$_.Company} | select Name, Count

….although to be honest, that’s not a great example, because most of the processes on my lappie-top have a blank company.

Print the first field (word) of every line (emulate cut -f 1 -d ‘ ‘)

foreach ($LINE in $(gc henry8.txt)) { (($LINE.trimstart()).split(''))[0] }

Handy regular expressions

Match something that looks like an IP address

This is horrible. I will come back to it when time allows…

$PossibleIP="200.100.50.280"

$Elements = $PossibleIP.split('.')

if ($Elements.length -ne 4)
{
  write-host "Not got 4 elements"
}

$ArrayOfFour = 0..3

foreach ($i in $ArrayOfFour)
{
  if ([int]$Elements[$i] -lt 256 -and [int]$Elements[$i] -gt -1)
  {
    write-host "Element $i IS in range 0-255"
  }
  else
  {
    write "Element $i IS NOT in range 0-255"}
}

Test if a number is in range 0-255

$N=4
if ([int]$N -lt 256 -and [int]$N -gt -1) {write-host "Number IS in range 0-255"} else {write "Number IS NOT in range 0-255"}

<?php /*

Match an IP address


*/?>
<?php /*

Check if the string looks like an email address


*/?>
<?php /*

Check if the string is a decimal number


*/?>

Check if the string is a hexadecimal number

I think this works:

$X = "21e" ; $Y = $X.length ; $X -match "[0123456789abcde]{$Y}"

A possibly better way to do this is to use [Convert]::ToInt32. If you try to convert a non-hex string from base 16 it retuns an error:

$ $X = "21f" ; [Convert]::ToInt32($X,16)
543

$ $X = "21g" ; [Convert]::ToInt32($X,16)

Exception calling "ToInt32" with "2" argument(s): "Additional non-parsable characters are at the end of the string."
At line:1 char:14
+ $X = "21g" ; [Convert]::ToInt32($X,16)
+              ~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : FormatException

With thanks to Michael Flanakin for his page on Powershell and hex.

Check if the string is an octal number

As per the previous one-liner, probably the best way to confirm whether or not a string is octal is to try to convert it from octal to decimal. It will error if it’s not octal.

$ [Convert]::ToInt32("123",8)
83
$ [Convert]::ToInt32("129",8)
Exception calling "ToInt32" with "2" argument(s): "Additional non-parsable characters are at the end of the string."
At line:1 char:1
+ [Convert]::ToInt32("129",8)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : FormatException

Check if the string is binary

As above, and indeed as above that.

$ [Convert]::ToInt32("10110",2)
22
$ [Convert]::ToInt32("10110",1)
Exception calling "ToInt32" with "2" argument(s): "Invalid Base."
At line:1 char:1
+ [Convert]::ToInt32("10110",1)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentException

<?php /*

Check if a word appears twice in the string


*/?>
<?php /*

Increase all numbers by one in the string


*/?>
<?php /*

Extract HTTP User-Agent string from the HTTP headers


*/?>
<?php /*

Match printable ASCII characters


*/?>
<?php /*

Match unprintable ASCII characters


*/?>
<?php /*

Match text between two HTML tags


*/?>
<?php /*

Replace all tags with


*/?>
<?php /*

Extract all matches from a regular expression


*/?>


Perl tricks

Print the version of a Perl module

Get-Module  | select name, version
Get-Module -listAvailable | select name, version

Note that the version of Powershell itself is given by

$PSVersionTable

Notes

1. I could make Id 7 look better by doing this:

PS C:UsersMatt> history 7,9 | select CommandLine | fl


CommandLine : foreach ($LINE in $(gc henry8.txt))
              {
                write-host $LINE
                write-host
              }

CommandLine : foreach ($LINE in $(gc henry8.txt)) {write-host $LINE ; write-host}

…but that’s more typing, and I’m fundamentally lazy. If I wasn’t lazy I probably wouldn’t have invested so much time in learning Powershell. The ‘shell for me is mainly about doing more stuff with less effort.