How to create a 7zip archive of files from a directory, excluding existing archives?












0















Want to 7zip all files in root/current folder except for all zip-files AND all 7z/7zip files. I can only get one of these to work at a time in one if ! statement:



for file in ./test2/*
do

if ! { `file $file | grep -i zip > /dev/null 2>&1` && `file $file | grep -i 7z > /dev/null 2>&1`; }; then

## Most of the zip utilities contain "zip" when checked for file type.
## grep for the expression that matches your case

7z a -mx0 -mmt2 -tzip "${file%/}.cbz" "$file"
rm -rf "$file"

fi
done



I have followed the "list" {list;}; standards from other posts, but no luck.





My current solution is to nest if statements, like so:



for file in ./test2/*
do
if ! `file $file | grep -i 7z > /dev/null 2>&1`; then

if ! `file $file | grep -i zip > /dev/null 2>&1`; then
## first if its not 7z, now also if not zip.

7z a -mx0 -mmt2 -tzip "${file%/}.cbz" "$file"
rm -rf "$file"

fi

fi

done


Only thing left is exclude directories. All files go. How to?










share|improve this question









New contributor




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

























    0















    Want to 7zip all files in root/current folder except for all zip-files AND all 7z/7zip files. I can only get one of these to work at a time in one if ! statement:



    for file in ./test2/*
    do

    if ! { `file $file | grep -i zip > /dev/null 2>&1` && `file $file | grep -i 7z > /dev/null 2>&1`; }; then

    ## Most of the zip utilities contain "zip" when checked for file type.
    ## grep for the expression that matches your case

    7z a -mx0 -mmt2 -tzip "${file%/}.cbz" "$file"
    rm -rf "$file"

    fi
    done



    I have followed the "list" {list;}; standards from other posts, but no luck.





    My current solution is to nest if statements, like so:



    for file in ./test2/*
    do
    if ! `file $file | grep -i 7z > /dev/null 2>&1`; then

    if ! `file $file | grep -i zip > /dev/null 2>&1`; then
    ## first if its not 7z, now also if not zip.

    7z a -mx0 -mmt2 -tzip "${file%/}.cbz" "$file"
    rm -rf "$file"

    fi

    fi

    done


    Only thing left is exclude directories. All files go. How to?










    share|improve this question









    New contributor




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























      0












      0








      0








      Want to 7zip all files in root/current folder except for all zip-files AND all 7z/7zip files. I can only get one of these to work at a time in one if ! statement:



      for file in ./test2/*
      do

      if ! { `file $file | grep -i zip > /dev/null 2>&1` && `file $file | grep -i 7z > /dev/null 2>&1`; }; then

      ## Most of the zip utilities contain "zip" when checked for file type.
      ## grep for the expression that matches your case

      7z a -mx0 -mmt2 -tzip "${file%/}.cbz" "$file"
      rm -rf "$file"

      fi
      done



      I have followed the "list" {list;}; standards from other posts, but no luck.





      My current solution is to nest if statements, like so:



      for file in ./test2/*
      do
      if ! `file $file | grep -i 7z > /dev/null 2>&1`; then

      if ! `file $file | grep -i zip > /dev/null 2>&1`; then
      ## first if its not 7z, now also if not zip.

      7z a -mx0 -mmt2 -tzip "${file%/}.cbz" "$file"
      rm -rf "$file"

      fi

      fi

      done


      Only thing left is exclude directories. All files go. How to?










      share|improve this question









      New contributor




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












      Want to 7zip all files in root/current folder except for all zip-files AND all 7z/7zip files. I can only get one of these to work at a time in one if ! statement:



      for file in ./test2/*
      do

      if ! { `file $file | grep -i zip > /dev/null 2>&1` && `file $file | grep -i 7z > /dev/null 2>&1`; }; then

      ## Most of the zip utilities contain "zip" when checked for file type.
      ## grep for the expression that matches your case

      7z a -mx0 -mmt2 -tzip "${file%/}.cbz" "$file"
      rm -rf "$file"

      fi
      done



      I have followed the "list" {list;}; standards from other posts, but no luck.





      My current solution is to nest if statements, like so:



      for file in ./test2/*
      do
      if ! `file $file | grep -i 7z > /dev/null 2>&1`; then

      if ! `file $file | grep -i zip > /dev/null 2>&1`; then
      ## first if its not 7z, now also if not zip.

      7z a -mx0 -mmt2 -tzip "${file%/}.cbz" "$file"
      rm -rf "$file"

      fi

      fi

      done


      Only thing left is exclude directories. All files go. How to?







      bash shell-script terminal file-types






      share|improve this question









      New contributor




      andyNilson 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 question









      New contributor




      andyNilson 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 question




      share|improve this question








      edited 2 hours ago









      200_success

      3,92711528




      3,92711528






      New contributor




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









      asked 10 hours ago









      andyNilsonandyNilson

      32




      32




      New contributor




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





      New contributor





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






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






















          1 Answer
          1






          active

          oldest

          votes


















          1














          Get the output of file separately and then use that in multiple tests, or in a case statement:



          for file in ./test2/*; do
          filetype=$( file "$file" )

          if [[ $filetype == *7z* ]] ||
          [[ $filetype == *zip* ]]
          then
          # skip these
          continue
          fi

          # rest of body of loop here
          done


          Or,



          for file in ./test2/*; do
          filetype=$( file "$file" )

          case $filetype in
          *7z*) continue ;; # skip these
          *zip*) continue ;; # and these
          esac

          # rest of body of loop here
          done


          You may also want to get file to output the MIME type instead of a free form text string. That could be done with file -i and would make the script slightly more portable (if you care about that). See the file(1) manual (man 1 file).



          To exclude directories, just use



          if [ -d "$file" ]; then
          continue
          fi


          before the call to file.



          Alternatively, use short-circuit syntax:



          [ -d "$file" ] && continue


          The continue statement, in all instances where it's used above, will skip the remainder of the current iteration and continue with the next iteration of the loop. I'm using when I have determined that the current value of $file is something that we don't want to process in this iteration. This is the opposite of what you do, which is to try to craft a set of tests for when the operations should be performed.



          A /bin/sh-compatible script would look like this in the end:



          #!/bin/sh

          for file in ./test2/*; do
          [ -d "$file" ] && continue

          filetype=$( file "$file" )

          case $filetype in
          *7z*) continue ;; # skip these
          *zip*) continue ;; # and these
          esac

          # rest of body of loop here
          done





          share|improve this answer


























          • Works perfectly. I put the: if [ -d "$file" ]; then ... before the 7z line. Does just what I want.

            – andyNilson
            9 hours ago













          • @andyNilson No. As I mentioned, it should go before the call to file, i.e. before assigning anything to filetype. Doing it later means you're calling file unnecessary.

            – Kusalananda
            9 hours ago













          • @ Kusalananda. Do i add it to filetype, to the for statement or in between?

            – andyNilson
            9 hours ago













          • @andyNilson Between. The test of whether $file is a directory should be the first thing that happens in the loop. If it is a directory, the rest of that iteration should be skipped with continue.

            – Kusalananda
            8 hours ago











          • Thanks for the clarifications. Added it before the filetype. Now working smoothly. Your last example for bin/sh works perfectly. My own 7z though, had to be fitted with -aou to keep it from overwriting files. As some files created already had 7z versions. Posting it above as a final solution.

            – andyNilson
            7 hours ago











          Your Answer








          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "106"
          };
          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: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          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
          });


          }
          });






          andyNilson is a new contributor. Be nice, and check out our Code of Conduct.










          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f504284%2fhow-to-create-a-7zip-archive-of-files-from-a-directory-excluding-existing-archi%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1














          Get the output of file separately and then use that in multiple tests, or in a case statement:



          for file in ./test2/*; do
          filetype=$( file "$file" )

          if [[ $filetype == *7z* ]] ||
          [[ $filetype == *zip* ]]
          then
          # skip these
          continue
          fi

          # rest of body of loop here
          done


          Or,



          for file in ./test2/*; do
          filetype=$( file "$file" )

          case $filetype in
          *7z*) continue ;; # skip these
          *zip*) continue ;; # and these
          esac

          # rest of body of loop here
          done


          You may also want to get file to output the MIME type instead of a free form text string. That could be done with file -i and would make the script slightly more portable (if you care about that). See the file(1) manual (man 1 file).



          To exclude directories, just use



          if [ -d "$file" ]; then
          continue
          fi


          before the call to file.



          Alternatively, use short-circuit syntax:



          [ -d "$file" ] && continue


          The continue statement, in all instances where it's used above, will skip the remainder of the current iteration and continue with the next iteration of the loop. I'm using when I have determined that the current value of $file is something that we don't want to process in this iteration. This is the opposite of what you do, which is to try to craft a set of tests for when the operations should be performed.



          A /bin/sh-compatible script would look like this in the end:



          #!/bin/sh

          for file in ./test2/*; do
          [ -d "$file" ] && continue

          filetype=$( file "$file" )

          case $filetype in
          *7z*) continue ;; # skip these
          *zip*) continue ;; # and these
          esac

          # rest of body of loop here
          done





          share|improve this answer


























          • Works perfectly. I put the: if [ -d "$file" ]; then ... before the 7z line. Does just what I want.

            – andyNilson
            9 hours ago













          • @andyNilson No. As I mentioned, it should go before the call to file, i.e. before assigning anything to filetype. Doing it later means you're calling file unnecessary.

            – Kusalananda
            9 hours ago













          • @ Kusalananda. Do i add it to filetype, to the for statement or in between?

            – andyNilson
            9 hours ago













          • @andyNilson Between. The test of whether $file is a directory should be the first thing that happens in the loop. If it is a directory, the rest of that iteration should be skipped with continue.

            – Kusalananda
            8 hours ago











          • Thanks for the clarifications. Added it before the filetype. Now working smoothly. Your last example for bin/sh works perfectly. My own 7z though, had to be fitted with -aou to keep it from overwriting files. As some files created already had 7z versions. Posting it above as a final solution.

            – andyNilson
            7 hours ago
















          1














          Get the output of file separately and then use that in multiple tests, or in a case statement:



          for file in ./test2/*; do
          filetype=$( file "$file" )

          if [[ $filetype == *7z* ]] ||
          [[ $filetype == *zip* ]]
          then
          # skip these
          continue
          fi

          # rest of body of loop here
          done


          Or,



          for file in ./test2/*; do
          filetype=$( file "$file" )

          case $filetype in
          *7z*) continue ;; # skip these
          *zip*) continue ;; # and these
          esac

          # rest of body of loop here
          done


          You may also want to get file to output the MIME type instead of a free form text string. That could be done with file -i and would make the script slightly more portable (if you care about that). See the file(1) manual (man 1 file).



          To exclude directories, just use



          if [ -d "$file" ]; then
          continue
          fi


          before the call to file.



          Alternatively, use short-circuit syntax:



          [ -d "$file" ] && continue


          The continue statement, in all instances where it's used above, will skip the remainder of the current iteration and continue with the next iteration of the loop. I'm using when I have determined that the current value of $file is something that we don't want to process in this iteration. This is the opposite of what you do, which is to try to craft a set of tests for when the operations should be performed.



          A /bin/sh-compatible script would look like this in the end:



          #!/bin/sh

          for file in ./test2/*; do
          [ -d "$file" ] && continue

          filetype=$( file "$file" )

          case $filetype in
          *7z*) continue ;; # skip these
          *zip*) continue ;; # and these
          esac

          # rest of body of loop here
          done





          share|improve this answer


























          • Works perfectly. I put the: if [ -d "$file" ]; then ... before the 7z line. Does just what I want.

            – andyNilson
            9 hours ago













          • @andyNilson No. As I mentioned, it should go before the call to file, i.e. before assigning anything to filetype. Doing it later means you're calling file unnecessary.

            – Kusalananda
            9 hours ago













          • @ Kusalananda. Do i add it to filetype, to the for statement or in between?

            – andyNilson
            9 hours ago













          • @andyNilson Between. The test of whether $file is a directory should be the first thing that happens in the loop. If it is a directory, the rest of that iteration should be skipped with continue.

            – Kusalananda
            8 hours ago











          • Thanks for the clarifications. Added it before the filetype. Now working smoothly. Your last example for bin/sh works perfectly. My own 7z though, had to be fitted with -aou to keep it from overwriting files. As some files created already had 7z versions. Posting it above as a final solution.

            – andyNilson
            7 hours ago














          1












          1








          1







          Get the output of file separately and then use that in multiple tests, or in a case statement:



          for file in ./test2/*; do
          filetype=$( file "$file" )

          if [[ $filetype == *7z* ]] ||
          [[ $filetype == *zip* ]]
          then
          # skip these
          continue
          fi

          # rest of body of loop here
          done


          Or,



          for file in ./test2/*; do
          filetype=$( file "$file" )

          case $filetype in
          *7z*) continue ;; # skip these
          *zip*) continue ;; # and these
          esac

          # rest of body of loop here
          done


          You may also want to get file to output the MIME type instead of a free form text string. That could be done with file -i and would make the script slightly more portable (if you care about that). See the file(1) manual (man 1 file).



          To exclude directories, just use



          if [ -d "$file" ]; then
          continue
          fi


          before the call to file.



          Alternatively, use short-circuit syntax:



          [ -d "$file" ] && continue


          The continue statement, in all instances where it's used above, will skip the remainder of the current iteration and continue with the next iteration of the loop. I'm using when I have determined that the current value of $file is something that we don't want to process in this iteration. This is the opposite of what you do, which is to try to craft a set of tests for when the operations should be performed.



          A /bin/sh-compatible script would look like this in the end:



          #!/bin/sh

          for file in ./test2/*; do
          [ -d "$file" ] && continue

          filetype=$( file "$file" )

          case $filetype in
          *7z*) continue ;; # skip these
          *zip*) continue ;; # and these
          esac

          # rest of body of loop here
          done





          share|improve this answer















          Get the output of file separately and then use that in multiple tests, or in a case statement:



          for file in ./test2/*; do
          filetype=$( file "$file" )

          if [[ $filetype == *7z* ]] ||
          [[ $filetype == *zip* ]]
          then
          # skip these
          continue
          fi

          # rest of body of loop here
          done


          Or,



          for file in ./test2/*; do
          filetype=$( file "$file" )

          case $filetype in
          *7z*) continue ;; # skip these
          *zip*) continue ;; # and these
          esac

          # rest of body of loop here
          done


          You may also want to get file to output the MIME type instead of a free form text string. That could be done with file -i and would make the script slightly more portable (if you care about that). See the file(1) manual (man 1 file).



          To exclude directories, just use



          if [ -d "$file" ]; then
          continue
          fi


          before the call to file.



          Alternatively, use short-circuit syntax:



          [ -d "$file" ] && continue


          The continue statement, in all instances where it's used above, will skip the remainder of the current iteration and continue with the next iteration of the loop. I'm using when I have determined that the current value of $file is something that we don't want to process in this iteration. This is the opposite of what you do, which is to try to craft a set of tests for when the operations should be performed.



          A /bin/sh-compatible script would look like this in the end:



          #!/bin/sh

          for file in ./test2/*; do
          [ -d "$file" ] && continue

          filetype=$( file "$file" )

          case $filetype in
          *7z*) continue ;; # skip these
          *zip*) continue ;; # and these
          esac

          # rest of body of loop here
          done






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 8 hours ago

























          answered 10 hours ago









          KusalanandaKusalananda

          133k17254417




          133k17254417













          • Works perfectly. I put the: if [ -d "$file" ]; then ... before the 7z line. Does just what I want.

            – andyNilson
            9 hours ago













          • @andyNilson No. As I mentioned, it should go before the call to file, i.e. before assigning anything to filetype. Doing it later means you're calling file unnecessary.

            – Kusalananda
            9 hours ago













          • @ Kusalananda. Do i add it to filetype, to the for statement or in between?

            – andyNilson
            9 hours ago













          • @andyNilson Between. The test of whether $file is a directory should be the first thing that happens in the loop. If it is a directory, the rest of that iteration should be skipped with continue.

            – Kusalananda
            8 hours ago











          • Thanks for the clarifications. Added it before the filetype. Now working smoothly. Your last example for bin/sh works perfectly. My own 7z though, had to be fitted with -aou to keep it from overwriting files. As some files created already had 7z versions. Posting it above as a final solution.

            – andyNilson
            7 hours ago



















          • Works perfectly. I put the: if [ -d "$file" ]; then ... before the 7z line. Does just what I want.

            – andyNilson
            9 hours ago













          • @andyNilson No. As I mentioned, it should go before the call to file, i.e. before assigning anything to filetype. Doing it later means you're calling file unnecessary.

            – Kusalananda
            9 hours ago













          • @ Kusalananda. Do i add it to filetype, to the for statement or in between?

            – andyNilson
            9 hours ago













          • @andyNilson Between. The test of whether $file is a directory should be the first thing that happens in the loop. If it is a directory, the rest of that iteration should be skipped with continue.

            – Kusalananda
            8 hours ago











          • Thanks for the clarifications. Added it before the filetype. Now working smoothly. Your last example for bin/sh works perfectly. My own 7z though, had to be fitted with -aou to keep it from overwriting files. As some files created already had 7z versions. Posting it above as a final solution.

            – andyNilson
            7 hours ago

















          Works perfectly. I put the: if [ -d "$file" ]; then ... before the 7z line. Does just what I want.

          – andyNilson
          9 hours ago







          Works perfectly. I put the: if [ -d "$file" ]; then ... before the 7z line. Does just what I want.

          – andyNilson
          9 hours ago















          @andyNilson No. As I mentioned, it should go before the call to file, i.e. before assigning anything to filetype. Doing it later means you're calling file unnecessary.

          – Kusalananda
          9 hours ago







          @andyNilson No. As I mentioned, it should go before the call to file, i.e. before assigning anything to filetype. Doing it later means you're calling file unnecessary.

          – Kusalananda
          9 hours ago















          @ Kusalananda. Do i add it to filetype, to the for statement or in between?

          – andyNilson
          9 hours ago







          @ Kusalananda. Do i add it to filetype, to the for statement or in between?

          – andyNilson
          9 hours ago















          @andyNilson Between. The test of whether $file is a directory should be the first thing that happens in the loop. If it is a directory, the rest of that iteration should be skipped with continue.

          – Kusalananda
          8 hours ago





          @andyNilson Between. The test of whether $file is a directory should be the first thing that happens in the loop. If it is a directory, the rest of that iteration should be skipped with continue.

          – Kusalananda
          8 hours ago













          Thanks for the clarifications. Added it before the filetype. Now working smoothly. Your last example for bin/sh works perfectly. My own 7z though, had to be fitted with -aou to keep it from overwriting files. As some files created already had 7z versions. Posting it above as a final solution.

          – andyNilson
          7 hours ago





          Thanks for the clarifications. Added it before the filetype. Now working smoothly. Your last example for bin/sh works perfectly. My own 7z though, had to be fitted with -aou to keep it from overwriting files. As some files created already had 7z versions. Posting it above as a final solution.

          – andyNilson
          7 hours ago










          andyNilson is a new contributor. Be nice, and check out our Code of Conduct.










          draft saved

          draft discarded


















          andyNilson is a new contributor. Be nice, and check out our Code of Conduct.













          andyNilson is a new contributor. Be nice, and check out our Code of Conduct.












          andyNilson is a new contributor. Be nice, and check out our Code of Conduct.
















          Thanks for contributing an answer to Unix & Linux Stack Exchange!


          • 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%2funix.stackexchange.com%2fquestions%2f504284%2fhow-to-create-a-7zip-archive-of-files-from-a-directory-excluding-existing-archi%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

          宮崎県

          濃尾地震

          シテ島