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





























    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



























      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
















      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















      share|improve this question













      share|improve this question




      share|improve this question








      edited Mar 4 at 23:28









      200_success

      3,95711529




      3,95711529










      asked Mar 4 at 15:31









      andyNilsonandyNilson

      32




      32






















          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
            Mar 4 at 16:03













          • @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
            Mar 4 at 16:06













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

            – andyNilson
            Mar 4 at 16:20













          • @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
            Mar 4 at 16:53











          • 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
            Mar 4 at 17:48











          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
          });


          }
          });














          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
            Mar 4 at 16:03













          • @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
            Mar 4 at 16:06













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

            – andyNilson
            Mar 4 at 16:20













          • @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
            Mar 4 at 16:53











          • 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
            Mar 4 at 17:48
















          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
            Mar 4 at 16:03













          • @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
            Mar 4 at 16:06













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

            – andyNilson
            Mar 4 at 16:20













          • @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
            Mar 4 at 16:53











          • 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
            Mar 4 at 17:48














          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 Mar 4 at 17:15

























          answered Mar 4 at 15:39









          KusalanandaKusalananda

          138k17258426




          138k17258426













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

            – andyNilson
            Mar 4 at 16:03













          • @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
            Mar 4 at 16:06













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

            – andyNilson
            Mar 4 at 16:20













          • @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
            Mar 4 at 16:53











          • 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
            Mar 4 at 17:48



















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

            – andyNilson
            Mar 4 at 16:03













          • @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
            Mar 4 at 16:06













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

            – andyNilson
            Mar 4 at 16:20













          • @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
            Mar 4 at 16:53











          • 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
            Mar 4 at 17:48

















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

          – andyNilson
          Mar 4 at 16:03







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

          – andyNilson
          Mar 4 at 16:03















          @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
          Mar 4 at 16:06







          @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
          Mar 4 at 16:06















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

          – andyNilson
          Mar 4 at 16:20







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

          – andyNilson
          Mar 4 at 16:20















          @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
          Mar 4 at 16:53





          @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
          Mar 4 at 16:53













          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
          Mar 4 at 17:48





          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
          Mar 4 at 17:48


















          draft saved

          draft discarded




















































          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

          How to reconfigure Docker Trusted Registry 2.x.x to use CEPH FS mount instead of NFS and other traditional...

          is 'sed' thread safe

          How to make a Squid Proxy server?