How can a batch file overwrite contents of output each time?











up vote
0
down vote

favorite












I have this batch file below, which is a simple emulation of Unix’s head command – it will read the first COUNT rows from the input .csv file (named as a command-line parameter). However, unlike the Unix command, it writes to a hard-coded output file. The only issue now is that this batch file will be called several times to create this output file and will keep appending the results to the output file. I can't change the >> to > since this is a for loop and will just keep overwriting a single line into my output file, which is incorrect. Does anyone have any ideas on how to overwrite the output .csv file each time the batch file is run?



@echo off

if [%1] == goto usage
if [%2] == goto usage

call :print_head %1 %2
goto :eof

REM
REM print_head
REM Prints the first non-blank %1 lines in the file %2.
REM
:print_head
setlocal EnableDelayedExpansion
set /a counter=0

for /f ^"usebackq^ eol^=^

^ delims^=^" %%a in (%2) do (
if "!counter!"=="%1" goto :eof
@echo>>trimmed.csv %%a
set /a counter+=1
)

goto :eof

:usage
echo Usage: head.bat COUNT FILENAME









share|improve this question




























    up vote
    0
    down vote

    favorite












    I have this batch file below, which is a simple emulation of Unix’s head command – it will read the first COUNT rows from the input .csv file (named as a command-line parameter). However, unlike the Unix command, it writes to a hard-coded output file. The only issue now is that this batch file will be called several times to create this output file and will keep appending the results to the output file. I can't change the >> to > since this is a for loop and will just keep overwriting a single line into my output file, which is incorrect. Does anyone have any ideas on how to overwrite the output .csv file each time the batch file is run?



    @echo off

    if [%1] == goto usage
    if [%2] == goto usage

    call :print_head %1 %2
    goto :eof

    REM
    REM print_head
    REM Prints the first non-blank %1 lines in the file %2.
    REM
    :print_head
    setlocal EnableDelayedExpansion
    set /a counter=0

    for /f ^"usebackq^ eol^=^

    ^ delims^=^" %%a in (%2) do (
    if "!counter!"=="%1" goto :eof
    @echo>>trimmed.csv %%a
    set /a counter+=1
    )

    goto :eof

    :usage
    echo Usage: head.bat COUNT FILENAME









    share|improve this question


























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      I have this batch file below, which is a simple emulation of Unix’s head command – it will read the first COUNT rows from the input .csv file (named as a command-line parameter). However, unlike the Unix command, it writes to a hard-coded output file. The only issue now is that this batch file will be called several times to create this output file and will keep appending the results to the output file. I can't change the >> to > since this is a for loop and will just keep overwriting a single line into my output file, which is incorrect. Does anyone have any ideas on how to overwrite the output .csv file each time the batch file is run?



      @echo off

      if [%1] == goto usage
      if [%2] == goto usage

      call :print_head %1 %2
      goto :eof

      REM
      REM print_head
      REM Prints the first non-blank %1 lines in the file %2.
      REM
      :print_head
      setlocal EnableDelayedExpansion
      set /a counter=0

      for /f ^"usebackq^ eol^=^

      ^ delims^=^" %%a in (%2) do (
      if "!counter!"=="%1" goto :eof
      @echo>>trimmed.csv %%a
      set /a counter+=1
      )

      goto :eof

      :usage
      echo Usage: head.bat COUNT FILENAME









      share|improve this question















      I have this batch file below, which is a simple emulation of Unix’s head command – it will read the first COUNT rows from the input .csv file (named as a command-line parameter). However, unlike the Unix command, it writes to a hard-coded output file. The only issue now is that this batch file will be called several times to create this output file and will keep appending the results to the output file. I can't change the >> to > since this is a for loop and will just keep overwriting a single line into my output file, which is incorrect. Does anyone have any ideas on how to overwrite the output .csv file each time the batch file is run?



      @echo off

      if [%1] == goto usage
      if [%2] == goto usage

      call :print_head %1 %2
      goto :eof

      REM
      REM print_head
      REM Prints the first non-blank %1 lines in the file %2.
      REM
      :print_head
      setlocal EnableDelayedExpansion
      set /a counter=0

      for /f ^"usebackq^ eol^=^

      ^ delims^=^" %%a in (%2) do (
      if "!counter!"=="%1" goto :eof
      @echo>>trimmed.csv %%a
      set /a counter+=1
      )

      goto :eof

      :usage
      echo Usage: head.bat COUNT FILENAME






      command-line batch-file csv redirection






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 2 days ago









      Scott

      15.4k113789




      15.4k113789










      asked Mar 20 '13 at 16:50









      batchnoober

      2126




      2126






















          4 Answers
          4






          active

          oldest

          votes

















          up vote
          3
          down vote



          accepted










          Rather than deleting the file, I would personally prefer to overwrite the file with 'nothing':



          type NUL>trimmed.csv


          Put it somewhere above the loop.



          This creates a blank file, or overwrites an existing file with an empty file, with the name trimmed.csv. Since it is overwriting, and not deleting and recreating, it should keep the original file creation date.






          share|improve this answer





















          • This is good. I actually thought about deleting it but this is a nicer option.
            – batchnoober
            Mar 22 '13 at 18:59


















          up vote
          4
          down vote













          Perhaps just delete it at the start of the batch (or at the top of the :print_head section)?



          Something like del trimmed.csv /Q.



          That way it's deleted on the next run, but still gets created and appended to while it's running the loop.






          share|improve this answer






























            up vote
            0
            down vote













            I know it's an old question; However,as I didn't see this potential answer given, I'm adding it nonetheless as it may be a preferable answer for some folks...



            Instead of just:



            @echo>>trimmed.csv %%a


            Which, as mentioned, will just append the existing output file, try using:



            if [[ "$counter" -eq 0 ]]; then 
            @echo > trimmed.csv %%a
            else
            @echo >> trimmed.csv %%a
            fi


            That way, you don't have to worry about checking if the file exists and deleting it if it does. And additionally, at the first line of output automatically overwrite an existing file as a new empty file or start a new file if it doesn't and then subsequently, it will append the remainder of the lines.



            Although, personally, I would probably use some formatted date appended or prepended to the file basename (i.e. 2018-11-17_trimmed.csv or trimmed_2018-11-17.csv) using the output from the 'date' command stuffed into a variable (so that 'date' isn't run for each loop iteration.) or even do both.






            share|improve this answer








            New contributor




            Mce128 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.

























              up vote
              0
              down vote













              Here’s a (IMO) simpler, more direct way:
              put the entire for loop into parentheses,
              and move the I/O redirection outside the parentheses —
              with > instead of >>:



              (
              for /f ^"usebackq^ eol^=^

              ^ delims^=^" %%a in (%2) do (
              if "!counter!"=="%1" goto :eof
              @echo %%a
              set /a counter+=1
              )
              ) > trimmed.csv


              So, when the loop is started, the file is opened for writing
              (clobbering the previous contents, if the file already / still exists). 
              The batch file then keeps the CSV file open as standard output
              for the entire duration of the loop,
              so anything written to standard output from within the loop
              will go into the CSV file.



              This might even be infinitesimally more efficient
              than the original version of the batch file,
              because that one (potentially)
              has to open and close the output file COUNT times,
              whereas my version needs to do it only once.






              share|improve this answer





















                Your Answer








                StackExchange.ready(function() {
                var channelOptions = {
                tags: "".split(" "),
                id: "3"
                };
                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',
                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%2fsuperuser.com%2fquestions%2f568982%2fhow-can-a-batch-file-overwrite-contents-of-output-each-time%23new-answer', 'question_page');
                }
                );

                Post as a guest















                Required, but never shown

























                4 Answers
                4






                active

                oldest

                votes








                4 Answers
                4






                active

                oldest

                votes









                active

                oldest

                votes






                active

                oldest

                votes








                up vote
                3
                down vote



                accepted










                Rather than deleting the file, I would personally prefer to overwrite the file with 'nothing':



                type NUL>trimmed.csv


                Put it somewhere above the loop.



                This creates a blank file, or overwrites an existing file with an empty file, with the name trimmed.csv. Since it is overwriting, and not deleting and recreating, it should keep the original file creation date.






                share|improve this answer





















                • This is good. I actually thought about deleting it but this is a nicer option.
                  – batchnoober
                  Mar 22 '13 at 18:59















                up vote
                3
                down vote



                accepted










                Rather than deleting the file, I would personally prefer to overwrite the file with 'nothing':



                type NUL>trimmed.csv


                Put it somewhere above the loop.



                This creates a blank file, or overwrites an existing file with an empty file, with the name trimmed.csv. Since it is overwriting, and not deleting and recreating, it should keep the original file creation date.






                share|improve this answer





















                • This is good. I actually thought about deleting it but this is a nicer option.
                  – batchnoober
                  Mar 22 '13 at 18:59













                up vote
                3
                down vote



                accepted







                up vote
                3
                down vote



                accepted






                Rather than deleting the file, I would personally prefer to overwrite the file with 'nothing':



                type NUL>trimmed.csv


                Put it somewhere above the loop.



                This creates a blank file, or overwrites an existing file with an empty file, with the name trimmed.csv. Since it is overwriting, and not deleting and recreating, it should keep the original file creation date.






                share|improve this answer












                Rather than deleting the file, I would personally prefer to overwrite the file with 'nothing':



                type NUL>trimmed.csv


                Put it somewhere above the loop.



                This creates a blank file, or overwrites an existing file with an empty file, with the name trimmed.csv. Since it is overwriting, and not deleting and recreating, it should keep the original file creation date.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Mar 20 '13 at 17:32









                Bob

                44.7k20135170




                44.7k20135170












                • This is good. I actually thought about deleting it but this is a nicer option.
                  – batchnoober
                  Mar 22 '13 at 18:59


















                • This is good. I actually thought about deleting it but this is a nicer option.
                  – batchnoober
                  Mar 22 '13 at 18:59
















                This is good. I actually thought about deleting it but this is a nicer option.
                – batchnoober
                Mar 22 '13 at 18:59




                This is good. I actually thought about deleting it but this is a nicer option.
                – batchnoober
                Mar 22 '13 at 18:59












                up vote
                4
                down vote













                Perhaps just delete it at the start of the batch (or at the top of the :print_head section)?



                Something like del trimmed.csv /Q.



                That way it's deleted on the next run, but still gets created and appended to while it's running the loop.






                share|improve this answer



























                  up vote
                  4
                  down vote













                  Perhaps just delete it at the start of the batch (or at the top of the :print_head section)?



                  Something like del trimmed.csv /Q.



                  That way it's deleted on the next run, but still gets created and appended to while it's running the loop.






                  share|improve this answer

























                    up vote
                    4
                    down vote










                    up vote
                    4
                    down vote









                    Perhaps just delete it at the start of the batch (or at the top of the :print_head section)?



                    Something like del trimmed.csv /Q.



                    That way it's deleted on the next run, but still gets created and appended to while it's running the loop.






                    share|improve this answer














                    Perhaps just delete it at the start of the batch (or at the top of the :print_head section)?



                    Something like del trimmed.csv /Q.



                    That way it's deleted on the next run, but still gets created and appended to while it's running the loop.







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Mar 20 '13 at 17:22

























                    answered Mar 20 '13 at 16:56









                    Ƭᴇcʜιᴇ007

                    98.1k14153212




                    98.1k14153212






















                        up vote
                        0
                        down vote













                        I know it's an old question; However,as I didn't see this potential answer given, I'm adding it nonetheless as it may be a preferable answer for some folks...



                        Instead of just:



                        @echo>>trimmed.csv %%a


                        Which, as mentioned, will just append the existing output file, try using:



                        if [[ "$counter" -eq 0 ]]; then 
                        @echo > trimmed.csv %%a
                        else
                        @echo >> trimmed.csv %%a
                        fi


                        That way, you don't have to worry about checking if the file exists and deleting it if it does. And additionally, at the first line of output automatically overwrite an existing file as a new empty file or start a new file if it doesn't and then subsequently, it will append the remainder of the lines.



                        Although, personally, I would probably use some formatted date appended or prepended to the file basename (i.e. 2018-11-17_trimmed.csv or trimmed_2018-11-17.csv) using the output from the 'date' command stuffed into a variable (so that 'date' isn't run for each loop iteration.) or even do both.






                        share|improve this answer








                        New contributor




                        Mce128 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                        Check out our Code of Conduct.






















                          up vote
                          0
                          down vote













                          I know it's an old question; However,as I didn't see this potential answer given, I'm adding it nonetheless as it may be a preferable answer for some folks...



                          Instead of just:



                          @echo>>trimmed.csv %%a


                          Which, as mentioned, will just append the existing output file, try using:



                          if [[ "$counter" -eq 0 ]]; then 
                          @echo > trimmed.csv %%a
                          else
                          @echo >> trimmed.csv %%a
                          fi


                          That way, you don't have to worry about checking if the file exists and deleting it if it does. And additionally, at the first line of output automatically overwrite an existing file as a new empty file or start a new file if it doesn't and then subsequently, it will append the remainder of the lines.



                          Although, personally, I would probably use some formatted date appended or prepended to the file basename (i.e. 2018-11-17_trimmed.csv or trimmed_2018-11-17.csv) using the output from the 'date' command stuffed into a variable (so that 'date' isn't run for each loop iteration.) or even do both.






                          share|improve this answer








                          New contributor




                          Mce128 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                          Check out our Code of Conduct.




















                            up vote
                            0
                            down vote










                            up vote
                            0
                            down vote









                            I know it's an old question; However,as I didn't see this potential answer given, I'm adding it nonetheless as it may be a preferable answer for some folks...



                            Instead of just:



                            @echo>>trimmed.csv %%a


                            Which, as mentioned, will just append the existing output file, try using:



                            if [[ "$counter" -eq 0 ]]; then 
                            @echo > trimmed.csv %%a
                            else
                            @echo >> trimmed.csv %%a
                            fi


                            That way, you don't have to worry about checking if the file exists and deleting it if it does. And additionally, at the first line of output automatically overwrite an existing file as a new empty file or start a new file if it doesn't and then subsequently, it will append the remainder of the lines.



                            Although, personally, I would probably use some formatted date appended or prepended to the file basename (i.e. 2018-11-17_trimmed.csv or trimmed_2018-11-17.csv) using the output from the 'date' command stuffed into a variable (so that 'date' isn't run for each loop iteration.) or even do both.






                            share|improve this answer








                            New contributor




                            Mce128 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                            Check out our Code of Conduct.









                            I know it's an old question; However,as I didn't see this potential answer given, I'm adding it nonetheless as it may be a preferable answer for some folks...



                            Instead of just:



                            @echo>>trimmed.csv %%a


                            Which, as mentioned, will just append the existing output file, try using:



                            if [[ "$counter" -eq 0 ]]; then 
                            @echo > trimmed.csv %%a
                            else
                            @echo >> trimmed.csv %%a
                            fi


                            That way, you don't have to worry about checking if the file exists and deleting it if it does. And additionally, at the first line of output automatically overwrite an existing file as a new empty file or start a new file if it doesn't and then subsequently, it will append the remainder of the lines.



                            Although, personally, I would probably use some formatted date appended or prepended to the file basename (i.e. 2018-11-17_trimmed.csv or trimmed_2018-11-17.csv) using the output from the 'date' command stuffed into a variable (so that 'date' isn't run for each loop iteration.) or even do both.







                            share|improve this answer








                            New contributor




                            Mce128 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                            Check out our Code of Conduct.









                            share|improve this answer



                            share|improve this answer






                            New contributor




                            Mce128 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                            Check out our Code of Conduct.









                            answered 2 days ago









                            Mce128

                            13




                            13




                            New contributor




                            Mce128 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                            Check out our Code of Conduct.





                            New contributor





                            Mce128 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                            Check out our Code of Conduct.






                            Mce128 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                            Check out our Code of Conduct.






















                                up vote
                                0
                                down vote













                                Here’s a (IMO) simpler, more direct way:
                                put the entire for loop into parentheses,
                                and move the I/O redirection outside the parentheses —
                                with > instead of >>:



                                (
                                for /f ^"usebackq^ eol^=^

                                ^ delims^=^" %%a in (%2) do (
                                if "!counter!"=="%1" goto :eof
                                @echo %%a
                                set /a counter+=1
                                )
                                ) > trimmed.csv


                                So, when the loop is started, the file is opened for writing
                                (clobbering the previous contents, if the file already / still exists). 
                                The batch file then keeps the CSV file open as standard output
                                for the entire duration of the loop,
                                so anything written to standard output from within the loop
                                will go into the CSV file.



                                This might even be infinitesimally more efficient
                                than the original version of the batch file,
                                because that one (potentially)
                                has to open and close the output file COUNT times,
                                whereas my version needs to do it only once.






                                share|improve this answer

























                                  up vote
                                  0
                                  down vote













                                  Here’s a (IMO) simpler, more direct way:
                                  put the entire for loop into parentheses,
                                  and move the I/O redirection outside the parentheses —
                                  with > instead of >>:



                                  (
                                  for /f ^"usebackq^ eol^=^

                                  ^ delims^=^" %%a in (%2) do (
                                  if "!counter!"=="%1" goto :eof
                                  @echo %%a
                                  set /a counter+=1
                                  )
                                  ) > trimmed.csv


                                  So, when the loop is started, the file is opened for writing
                                  (clobbering the previous contents, if the file already / still exists). 
                                  The batch file then keeps the CSV file open as standard output
                                  for the entire duration of the loop,
                                  so anything written to standard output from within the loop
                                  will go into the CSV file.



                                  This might even be infinitesimally more efficient
                                  than the original version of the batch file,
                                  because that one (potentially)
                                  has to open and close the output file COUNT times,
                                  whereas my version needs to do it only once.






                                  share|improve this answer























                                    up vote
                                    0
                                    down vote










                                    up vote
                                    0
                                    down vote









                                    Here’s a (IMO) simpler, more direct way:
                                    put the entire for loop into parentheses,
                                    and move the I/O redirection outside the parentheses —
                                    with > instead of >>:



                                    (
                                    for /f ^"usebackq^ eol^=^

                                    ^ delims^=^" %%a in (%2) do (
                                    if "!counter!"=="%1" goto :eof
                                    @echo %%a
                                    set /a counter+=1
                                    )
                                    ) > trimmed.csv


                                    So, when the loop is started, the file is opened for writing
                                    (clobbering the previous contents, if the file already / still exists). 
                                    The batch file then keeps the CSV file open as standard output
                                    for the entire duration of the loop,
                                    so anything written to standard output from within the loop
                                    will go into the CSV file.



                                    This might even be infinitesimally more efficient
                                    than the original version of the batch file,
                                    because that one (potentially)
                                    has to open and close the output file COUNT times,
                                    whereas my version needs to do it only once.






                                    share|improve this answer












                                    Here’s a (IMO) simpler, more direct way:
                                    put the entire for loop into parentheses,
                                    and move the I/O redirection outside the parentheses —
                                    with > instead of >>:



                                    (
                                    for /f ^"usebackq^ eol^=^

                                    ^ delims^=^" %%a in (%2) do (
                                    if "!counter!"=="%1" goto :eof
                                    @echo %%a
                                    set /a counter+=1
                                    )
                                    ) > trimmed.csv


                                    So, when the loop is started, the file is opened for writing
                                    (clobbering the previous contents, if the file already / still exists). 
                                    The batch file then keeps the CSV file open as standard output
                                    for the entire duration of the loop,
                                    so anything written to standard output from within the loop
                                    will go into the CSV file.



                                    This might even be infinitesimally more efficient
                                    than the original version of the batch file,
                                    because that one (potentially)
                                    has to open and close the output file COUNT times,
                                    whereas my version needs to do it only once.







                                    share|improve this answer












                                    share|improve this answer



                                    share|improve this answer










                                    answered 2 days ago









                                    Scott

                                    15.4k113789




                                    15.4k113789






























                                         

                                        draft saved


                                        draft discarded



















































                                         


                                        draft saved


                                        draft discarded














                                        StackExchange.ready(
                                        function () {
                                        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsuperuser.com%2fquestions%2f568982%2fhow-can-a-batch-file-overwrite-contents-of-output-each-time%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

                                        Mouse cursor on multiple screens with different PPI

                                        Agildo Ribeiro

                                        Sometime when accessing a menu: “Ubuntu 16.04 has experienced an internal error”