Increment counter inside Foreach-Object loop












2















I want to output each line in a text document into its own document where the output documents are named 1.txt, 2.txt, etc.
This is my initial code that reads the text documents and outputs the lines one by one.



get-content "artists.txt" | Foreach-Object {$_ | set-content "artists$counter.txt"}


But as you can imagine, this outputs always to the same document.



I have tried



get-content "artists.txt" | 
Foreach-Object {$_ | set-content "artists$counter.txt" } {$counter++}


as I have seen suggested online and while this increases the counter, it doesn't do what I want (since it still outputs to the same file).



Not really sure where to insert the counter++ here as inside the Foreach-Object loop itself gives me an error (unless I'm inserting it wrong).



Thanks.










share|improve this question





























    2















    I want to output each line in a text document into its own document where the output documents are named 1.txt, 2.txt, etc.
    This is my initial code that reads the text documents and outputs the lines one by one.



    get-content "artists.txt" | Foreach-Object {$_ | set-content "artists$counter.txt"}


    But as you can imagine, this outputs always to the same document.



    I have tried



    get-content "artists.txt" | 
    Foreach-Object {$_ | set-content "artists$counter.txt" } {$counter++}


    as I have seen suggested online and while this increases the counter, it doesn't do what I want (since it still outputs to the same file).



    Not really sure where to insert the counter++ here as inside the Foreach-Object loop itself gives me an error (unless I'm inserting it wrong).



    Thanks.










    share|improve this question



























      2












      2








      2








      I want to output each line in a text document into its own document where the output documents are named 1.txt, 2.txt, etc.
      This is my initial code that reads the text documents and outputs the lines one by one.



      get-content "artists.txt" | Foreach-Object {$_ | set-content "artists$counter.txt"}


      But as you can imagine, this outputs always to the same document.



      I have tried



      get-content "artists.txt" | 
      Foreach-Object {$_ | set-content "artists$counter.txt" } {$counter++}


      as I have seen suggested online and while this increases the counter, it doesn't do what I want (since it still outputs to the same file).



      Not really sure where to insert the counter++ here as inside the Foreach-Object loop itself gives me an error (unless I'm inserting it wrong).



      Thanks.










      share|improve this question
















      I want to output each line in a text document into its own document where the output documents are named 1.txt, 2.txt, etc.
      This is my initial code that reads the text documents and outputs the lines one by one.



      get-content "artists.txt" | Foreach-Object {$_ | set-content "artists$counter.txt"}


      But as you can imagine, this outputs always to the same document.



      I have tried



      get-content "artists.txt" | 
      Foreach-Object {$_ | set-content "artists$counter.txt" } {$counter++}


      as I have seen suggested online and while this increases the counter, it doesn't do what I want (since it still outputs to the same file).



      Not really sure where to insert the counter++ here as inside the Foreach-Object loop itself gives me an error (unless I'm inserting it wrong).



      Thanks.







      powershell loops foreach






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 27 '18 at 13:48









      mklement0

      131k20245281




      131k20245281










      asked Nov 26 '18 at 18:45









      Sharert FukaeSharert Fukae

      253




      253
























          3 Answers
          3






          active

          oldest

          votes


















          4














          In your case, you can use the ReadCount property returned by the Get-Content cmdlet:



          get-content "artists.txt" | Foreach-Object {$_ | set-content "artists$($_.ReadCount).txt" }





          share|improve this answer































            3














            Martin Brandl's helpful answer provides an effective solution based on the - obscurely named - ReadCount property that Get-Content adds to each input line, which reflects the 1-based line number.



            Using a delay-bind script block enables a solution that is both shorter and noticeably faster:



            Get-Content artists.txt | Set-Content -LiteralPath { "artists$($_.ReadCount).txt" }




            As for what you tried:



            Variable $counter must be incremented in the ForEach-Object command's -Process block, i.e., the block that is executed for each input object (and is typically the only block specified, positionally).



            The 2nd script block you passed, {$counter++}, binds to the -End parameter, meaning the block to be executed once, after all pipeline objects have been received.



            Therefore, you could have used the following:



            $counter = 0
            Get-Content artists.txt | Foreach-Object {
            $_ | Set-Content "artists$((++$counter)).txt"
            }


            The increment operation is embedded in the expandable string for brevity, but you could make it a separate statement.



            Note the use of an extra pair of (...) around expression ++$counter, so as to ensure that the expression's value is also output; by default, ++ just increments a variable's value, but doesn't produce output.

            The outer $(...) - the subexpression operator - is needed in order to embed expressions or commands in expandable strings ("...").






            share|improve this answer

































              1














              In one-liners, the For-Each object has three positional blocks: begin, process and end:



              ...<piped objects>... | For-Each {...begin...} {...process...} {...end...}


              An easy and general way to set up a counter is:



              ...<piped objects>... | For-Each {$counter = 0} {...process...} {...end...}


              because if you need to reuse the one-liner, the $counter variable will not be reset. You can also add code to the begin block to start the counter at something else as well.



              For your particular case, we just have to initialize $counter in a begin block and use mklement0's answer:



              get-content "artists.txt" | Foreach-Object {$counter = 0} {$_ | set-content "artists$((++$counter.txt))"}


              You could even use the end block to output a summary:



              For-Each {...} {...} {Write-Host "There were $counter lines read and $counter files created"}





              share|improve this answer

























                Your Answer






                StackExchange.ifUsing("editor", function () {
                StackExchange.using("externalEditor", function () {
                StackExchange.using("snippets", function () {
                StackExchange.snippets.init();
                });
                });
                }, "code-snippets");

                StackExchange.ready(function() {
                var channelOptions = {
                tags: "".split(" "),
                id: "1"
                };
                initTagRenderer("".split(" "), "".split(" "), channelOptions);

                StackExchange.using("externalEditor", function() {
                // Have to fire editor after snippets, if snippets enabled
                if (StackExchange.settings.snippets.snippetsEnabled) {
                StackExchange.using("snippets", function() {
                createEditor();
                });
                }
                else {
                createEditor();
                }
                });

                function createEditor() {
                StackExchange.prepareEditor({
                heartbeatType: 'answer',
                autoActivateHeartbeat: false,
                convertImagesToLinks: true,
                noModals: true,
                showLowRepImageUploadWarning: true,
                reputationToPostImages: 10,
                bindNavPrevention: true,
                postfix: "",
                imageUploader: {
                brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
                contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
                allowUrls: true
                },
                onDemand: true,
                discardSelector: ".discard-answer"
                ,immediatelyShowMarkdownHelp:true
                });


                }
                });














                draft saved

                draft discarded


















                StackExchange.ready(
                function () {
                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53487243%2fincrement-counter-inside-foreach-object-loop%23new-answer', 'question_page');
                }
                );

                Post as a guest















                Required, but never shown

























                3 Answers
                3






                active

                oldest

                votes








                3 Answers
                3






                active

                oldest

                votes









                active

                oldest

                votes






                active

                oldest

                votes









                4














                In your case, you can use the ReadCount property returned by the Get-Content cmdlet:



                get-content "artists.txt" | Foreach-Object {$_ | set-content "artists$($_.ReadCount).txt" }





                share|improve this answer




























                  4














                  In your case, you can use the ReadCount property returned by the Get-Content cmdlet:



                  get-content "artists.txt" | Foreach-Object {$_ | set-content "artists$($_.ReadCount).txt" }





                  share|improve this answer


























                    4












                    4








                    4







                    In your case, you can use the ReadCount property returned by the Get-Content cmdlet:



                    get-content "artists.txt" | Foreach-Object {$_ | set-content "artists$($_.ReadCount).txt" }





                    share|improve this answer













                    In your case, you can use the ReadCount property returned by the Get-Content cmdlet:



                    get-content "artists.txt" | Foreach-Object {$_ | set-content "artists$($_.ReadCount).txt" }






                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Nov 26 '18 at 18:53









                    Martin BrandlMartin Brandl

                    35.2k105287




                    35.2k105287

























                        3














                        Martin Brandl's helpful answer provides an effective solution based on the - obscurely named - ReadCount property that Get-Content adds to each input line, which reflects the 1-based line number.



                        Using a delay-bind script block enables a solution that is both shorter and noticeably faster:



                        Get-Content artists.txt | Set-Content -LiteralPath { "artists$($_.ReadCount).txt" }




                        As for what you tried:



                        Variable $counter must be incremented in the ForEach-Object command's -Process block, i.e., the block that is executed for each input object (and is typically the only block specified, positionally).



                        The 2nd script block you passed, {$counter++}, binds to the -End parameter, meaning the block to be executed once, after all pipeline objects have been received.



                        Therefore, you could have used the following:



                        $counter = 0
                        Get-Content artists.txt | Foreach-Object {
                        $_ | Set-Content "artists$((++$counter)).txt"
                        }


                        The increment operation is embedded in the expandable string for brevity, but you could make it a separate statement.



                        Note the use of an extra pair of (...) around expression ++$counter, so as to ensure that the expression's value is also output; by default, ++ just increments a variable's value, but doesn't produce output.

                        The outer $(...) - the subexpression operator - is needed in order to embed expressions or commands in expandable strings ("...").






                        share|improve this answer






























                          3














                          Martin Brandl's helpful answer provides an effective solution based on the - obscurely named - ReadCount property that Get-Content adds to each input line, which reflects the 1-based line number.



                          Using a delay-bind script block enables a solution that is both shorter and noticeably faster:



                          Get-Content artists.txt | Set-Content -LiteralPath { "artists$($_.ReadCount).txt" }




                          As for what you tried:



                          Variable $counter must be incremented in the ForEach-Object command's -Process block, i.e., the block that is executed for each input object (and is typically the only block specified, positionally).



                          The 2nd script block you passed, {$counter++}, binds to the -End parameter, meaning the block to be executed once, after all pipeline objects have been received.



                          Therefore, you could have used the following:



                          $counter = 0
                          Get-Content artists.txt | Foreach-Object {
                          $_ | Set-Content "artists$((++$counter)).txt"
                          }


                          The increment operation is embedded in the expandable string for brevity, but you could make it a separate statement.



                          Note the use of an extra pair of (...) around expression ++$counter, so as to ensure that the expression's value is also output; by default, ++ just increments a variable's value, but doesn't produce output.

                          The outer $(...) - the subexpression operator - is needed in order to embed expressions or commands in expandable strings ("...").






                          share|improve this answer




























                            3












                            3








                            3







                            Martin Brandl's helpful answer provides an effective solution based on the - obscurely named - ReadCount property that Get-Content adds to each input line, which reflects the 1-based line number.



                            Using a delay-bind script block enables a solution that is both shorter and noticeably faster:



                            Get-Content artists.txt | Set-Content -LiteralPath { "artists$($_.ReadCount).txt" }




                            As for what you tried:



                            Variable $counter must be incremented in the ForEach-Object command's -Process block, i.e., the block that is executed for each input object (and is typically the only block specified, positionally).



                            The 2nd script block you passed, {$counter++}, binds to the -End parameter, meaning the block to be executed once, after all pipeline objects have been received.



                            Therefore, you could have used the following:



                            $counter = 0
                            Get-Content artists.txt | Foreach-Object {
                            $_ | Set-Content "artists$((++$counter)).txt"
                            }


                            The increment operation is embedded in the expandable string for brevity, but you could make it a separate statement.



                            Note the use of an extra pair of (...) around expression ++$counter, so as to ensure that the expression's value is also output; by default, ++ just increments a variable's value, but doesn't produce output.

                            The outer $(...) - the subexpression operator - is needed in order to embed expressions or commands in expandable strings ("...").






                            share|improve this answer















                            Martin Brandl's helpful answer provides an effective solution based on the - obscurely named - ReadCount property that Get-Content adds to each input line, which reflects the 1-based line number.



                            Using a delay-bind script block enables a solution that is both shorter and noticeably faster:



                            Get-Content artists.txt | Set-Content -LiteralPath { "artists$($_.ReadCount).txt" }




                            As for what you tried:



                            Variable $counter must be incremented in the ForEach-Object command's -Process block, i.e., the block that is executed for each input object (and is typically the only block specified, positionally).



                            The 2nd script block you passed, {$counter++}, binds to the -End parameter, meaning the block to be executed once, after all pipeline objects have been received.



                            Therefore, you could have used the following:



                            $counter = 0
                            Get-Content artists.txt | Foreach-Object {
                            $_ | Set-Content "artists$((++$counter)).txt"
                            }


                            The increment operation is embedded in the expandable string for brevity, but you could make it a separate statement.



                            Note the use of an extra pair of (...) around expression ++$counter, so as to ensure that the expression's value is also output; by default, ++ just increments a variable's value, but doesn't produce output.

                            The outer $(...) - the subexpression operator - is needed in order to embed expressions or commands in expandable strings ("...").







                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited Nov 27 '18 at 13:46

























                            answered Nov 27 '18 at 5:40









                            mklement0mklement0

                            131k20245281




                            131k20245281























                                1














                                In one-liners, the For-Each object has three positional blocks: begin, process and end:



                                ...<piped objects>... | For-Each {...begin...} {...process...} {...end...}


                                An easy and general way to set up a counter is:



                                ...<piped objects>... | For-Each {$counter = 0} {...process...} {...end...}


                                because if you need to reuse the one-liner, the $counter variable will not be reset. You can also add code to the begin block to start the counter at something else as well.



                                For your particular case, we just have to initialize $counter in a begin block and use mklement0's answer:



                                get-content "artists.txt" | Foreach-Object {$counter = 0} {$_ | set-content "artists$((++$counter.txt))"}


                                You could even use the end block to output a summary:



                                For-Each {...} {...} {Write-Host "There were $counter lines read and $counter files created"}





                                share|improve this answer






























                                  1














                                  In one-liners, the For-Each object has three positional blocks: begin, process and end:



                                  ...<piped objects>... | For-Each {...begin...} {...process...} {...end...}


                                  An easy and general way to set up a counter is:



                                  ...<piped objects>... | For-Each {$counter = 0} {...process...} {...end...}


                                  because if you need to reuse the one-liner, the $counter variable will not be reset. You can also add code to the begin block to start the counter at something else as well.



                                  For your particular case, we just have to initialize $counter in a begin block and use mklement0's answer:



                                  get-content "artists.txt" | Foreach-Object {$counter = 0} {$_ | set-content "artists$((++$counter.txt))"}


                                  You could even use the end block to output a summary:



                                  For-Each {...} {...} {Write-Host "There were $counter lines read and $counter files created"}





                                  share|improve this answer




























                                    1












                                    1








                                    1







                                    In one-liners, the For-Each object has three positional blocks: begin, process and end:



                                    ...<piped objects>... | For-Each {...begin...} {...process...} {...end...}


                                    An easy and general way to set up a counter is:



                                    ...<piped objects>... | For-Each {$counter = 0} {...process...} {...end...}


                                    because if you need to reuse the one-liner, the $counter variable will not be reset. You can also add code to the begin block to start the counter at something else as well.



                                    For your particular case, we just have to initialize $counter in a begin block and use mklement0's answer:



                                    get-content "artists.txt" | Foreach-Object {$counter = 0} {$_ | set-content "artists$((++$counter.txt))"}


                                    You could even use the end block to output a summary:



                                    For-Each {...} {...} {Write-Host "There were $counter lines read and $counter files created"}





                                    share|improve this answer















                                    In one-liners, the For-Each object has three positional blocks: begin, process and end:



                                    ...<piped objects>... | For-Each {...begin...} {...process...} {...end...}


                                    An easy and general way to set up a counter is:



                                    ...<piped objects>... | For-Each {$counter = 0} {...process...} {...end...}


                                    because if you need to reuse the one-liner, the $counter variable will not be reset. You can also add code to the begin block to start the counter at something else as well.



                                    For your particular case, we just have to initialize $counter in a begin block and use mklement0's answer:



                                    get-content "artists.txt" | Foreach-Object {$counter = 0} {$_ | set-content "artists$((++$counter.txt))"}


                                    You could even use the end block to output a summary:



                                    For-Each {...} {...} {Write-Host "There were $counter lines read and $counter files created"}






                                    share|improve this answer














                                    share|improve this answer



                                    share|improve this answer








                                    edited Nov 27 '18 at 19:44

























                                    answered Nov 27 '18 at 19:26









                                    gvkvgvkv

                                    1,07411732




                                    1,07411732






























                                        draft saved

                                        draft discarded




















































                                        Thanks for contributing an answer to Stack Overflow!


                                        • Please be sure to answer the question. Provide details and share your research!

                                        But avoid



                                        • Asking for help, clarification, or responding to other answers.

                                        • Making statements based on opinion; back them up with references or personal experience.


                                        To learn more, see our tips on writing great answers.




                                        draft saved


                                        draft discarded














                                        StackExchange.ready(
                                        function () {
                                        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53487243%2fincrement-counter-inside-foreach-object-loop%23new-answer', 'question_page');
                                        }
                                        );

                                        Post as a guest















                                        Required, but never shown





















































                                        Required, but never shown














                                        Required, but never shown












                                        Required, but never shown







                                        Required, but never shown

































                                        Required, but never shown














                                        Required, but never shown












                                        Required, but never shown







                                        Required, but never shown







                                        Popular posts from this blog

                                        A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

                                        Calculate evaluation metrics using cross_val_predict sklearn

                                        Insert data from modal to MySQL (multiple modal on website)