1

I am getting stuck here:

$file = gci C:\...\test\ | %{$_.name}
for ($i=0; $i -lt 100; $i++) {
  $array_$i =  gc C:\...\test\$($file[$i])
}

I am just trying to create multiple arrays for each text file in the directory.

Everything is working fine except the array name being declared - $array_$i.

3 Answers 3

2

PowerShell doesn't support variable variables (like php for example).

Use a hash table instead:

$files = gci C:\...\test\ | % {$_.Name}
$fileArrays = @{}
for ($i=0;$i -lt $files.Count; $i++){ 
    $fileArrays[$i] =  gc C:\...\test\$($file[$i]) 
}

Depending on what the purpose is, I would probably use the file name as the key instead. You're routine can also be simplified by:

$fileArrays = @{}
Get-ChildItem C:\...\test\ |ForEach-Object {
    $fileArrays[$_.Name] = Get-Content $_.FullName
}
Sign up to request clarification or add additional context in comments.

5 Comments

Command runs but it is giving nothing. $fileArrays[0] ................... no output
Which approach are you using? The first or the second?
The first approach.
I will still suggest you to use arraylist in this case. Then adding into that will be easy by using just the dot method.
The second approach works. I have name,value pairs of files and data in hash table. But it is complex to make a loop to call the hash object values for further operations as it does not use indexing.
2

you can use this script easy to add your file in your array :

$array =New-Object System.Collections.ArrayList
dir c:\testpath | %{$content = gc $_.FullName;$array.Add($content) > $null}

2 Comments

But it will not create a nested array. I need it to be nested or different dynamic arrays because I have to do modifications in each file.
@iamsmith41 : you can declare 2 array and make it nested .
1

Personally, I would pick one of the suggestions already presented. Using some kind of collection data structure usually greatly simplifies handling a number of distinct, but similar items.

  • Create an array of arrays:

    $array = @()
    Get-ChildItem C:\...\test | Select-Object -First 100 | ForEach-Object {
      $array += ,@(Get-Content $_.FullName)
    }
    

    Running the Get-Content call in an array subexpression and prepending it with the unary comma operator ensures that you append a nested array instead of each element being appended individually:

    [
      [ 'foo', 'bar', ... ],
      [ 'baz', ... ],
      ...
    ]
    

    rather than

    [
      'foo',
      'bar',
      'baz',
      ...
    ]
    
  • Create a hashtable of arrays:

    $ht = @{}
    Get-ChildItem C:\...\test | Select-Object -First 100 | ForEach-Object {
      $ht[$_.Name] = Get-Content $_.FullName
    }
    

    Using a hashtable is preferable if you need to be able to look up content by a particular key (in this example the filename) instead of an index.

    {
      'something': [ 'foo', 'bar', ... ],
      'other':     [ 'baz', ... ],
      ...
    }
    

    Note that you'll have to choose a different key if you have duplicate filenames, though (e.g. in different subfolders).

If, however, for some reason you must create individual variables for each content array you can do so with the New-Variable cmdlet:

$i = 0
Get-ChildItem C:\...\test | Select-Object -First 100 | ForEach-Object {
  New-Variable -Name "array_$i" -Value (Get-Content $_.FullName)
  $i++
}

4 Comments

At first I went for the third option as it was looking perfect for my case but the arrays that were dynamically created were not giving any output, none. I checked it is working fine for single array but not working in loop when combining with $i. It is also not giving any error on execution. At second I went for the nesting (first one) as it was also meeting my purpose. And it worked well. I can call files data based on indexing. Fine. But my goal still remaining.
My goal is - To call each file data based on indexing from nested array and remove last three lines. So- $array = New-Object Sytem.Collections.Arraylist; Get-ChildItem C:\...\test | ForEach-Object { $array += ,@(Get-Content $_.FullName) }; $array[0].removerange($array[0].count-2,2) But it throws error that removerange is not recognised. I checked - $array[0] | gm and removerange method was indeed not there. Just Remove and Removeat. How to proceed for this?
Ok. I marked the answer. But just let me know how to get it done( removerange() method ). Thanks in advance.
$array += ,[Collections.ArrayList]@(Get-Content $_.FullName) should probably suffice. If you need further help please post a new question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.