2

I have lines that consist of identical halves from which I want to remove one half; e.g, 'AbcAbc' should become 'Abc'.

The data always looks like:

10.22.20.106/tcp/8010.22.20.106/tcp/80
10.22.20.46/tcp/44310.22.20.46/tcp/443
10.22.20.90/tcp/44310.22.20.90/tcp/443
10.22.20.90/tcp/8010.22.20.90/tcp/80
10.22.20.89/tcp/44310.22.20.89/tcp/443
10.22.20.89/tcp/8010.22.20.89/tcp/80
10.22.20.29/tcp/44310.22.20.29/tcp/443
10.22.20.29/tcp/8010.22.20.29/tcp/80
10.22.20.122/tcp/44310.22.20.122/tcp/443
10.22.20.123/tcp/44310.22.20.123/tcp/443
10.22.20.79/tcp/44310.22.20.79/tcp/443
10.22.20.79/tcp/8010.22.20.79/tcp/80
10.22.20.78/tcp/44310.22.20.78/tcp/443
10.22.20.78/tcp/8010.22.20.78/tcp/80
10.22.20.74/tcp/44310.22.20.74/tcp/443
10.22.20.74/tcp/8010.22.20.74/tcp/80
10.22.20.22/tcp/44310.22.20.22/tcp/443
10.22.20.22/tcp/8010.22.20.22/tcp/80
10.22.20.99/tcp/44310.22.20.99/tcp/443
10.22.20.99/tcp/8010.22.20.99/tcp/80
10.22.20.54/tcp/44310.22.20.54/tcp/443
10.22.20.54/tcp/8010.22.20.54/tcp/80

I count the number of characters in the string and then halve it, but not sure how to use the calculated (halved) number of characters to cut the original string.

$vip_ip = $vip_line.("Virtual IP Address/Protocol/Port")
$half_string = $vip_ip.length /2

$vip_ip.length 44

$half_string 22

$vip_cut = $vip_ip.(0,-$halfstring)
mklement0
  • 382,024
  • 64
  • 607
  • 775
Paul Dawson
  • 1,332
  • 14
  • 27

2 Answers2

3

Matt's answer is the way to go, but just to present a regex-based alternative with
-replace, mostly as an interesting experiment:

Note: While this solution is concise, it's obscure and 2-3 times slower in my tests than the .Substring()-based approach.

# Extract one half of the input string consisting of identical halves.
PS> '10.22.20.54/tcp/44310.22.20.54/tcp/443' -replace '^(.+)\1$', '$1'
10.22.20.54/tcp/443
  • Regex subexpression ^(.+) matches one or more (+) (non-newline) characters (.) at the start (^) of the string and captures them (...) in a capture group.

  • \1$ matches a backreference (\1), which refers to what the (1st and only) capture group matched, at the end of the string ($).
    In effect, the whole regex will only match if the input consists of identical halves.

  • $1 as the -regex replacement operand then returns what the (1st and only) capture group matched, which is the input string's first half.

Note that such a regex is inefficient, because it requires a lot of backtracking, given that the halfway point isn't known in advance.
Using a non-greedy modifier (+? instead of +) works too in this case, but in practice seems to make no difference in terms of performance (presumably, use of .+? then requires an equal number of "forward tracking" attempts).

mklement0
  • 382,024
  • 64
  • 607
  • 775
2

You are trying to gather the information that you would need for the string method "".SubString()

In your case you just need something like this:

$vip_ip.substring(0,$halfstring)

From the start of the string and go halfway. Could also start from halfway to the end as well since the answer is the same. SubString() supports both overloads.

$vip_ip.substring($halfstring)
Matt
  • 45,022
  • 8
  • 78
  • 119