How to create a script to make a structure and sort files by moving them into directories?












1















I have a bunch of files which all have a first line being a date. All of them start with the same first 2 letters being "ff". I need to create a script which would use that first line in all files and sort them in directories creating these directories as well.



For example 1 file contains that:



Cat file



I need to extract the full date moving all files into directories for year then sub directories for month and another sub for day. So far I have this script which only moves files by year. I was told that I could use -p function, but really I have been using UNIX for 3 days so got confused now.



script










share|improve this question




















  • 2





    Please don't post pictures of text. Copy and paste the text instead. This makes it far easier to read - and for us to copy and test.

    – roaima
    May 24 '18 at 14:28













  • 1. Don't use for file in $(ls ff*) but use for file ff* instead. 2. Put your $variables into double quotes. For example mkdir "$test" instead of just mkdir $test. You will get an error if you try to create a directory that already exists. You can protect against that, or tell mkdir not to worry if it already exists with mkdir -p "$test". 3. In your first screenshot I can see only one file with a name starting with ff. 4. If the file starts with ff (line 7) it can't begin with a year (line 9).. Are you sure your requirements are correct?

    – roaima
    May 24 '18 at 14:36













  • @roaima meant for file in ff* I guess. And you should place head before cut for better performance.

    – RoVo
    May 24 '18 at 14:51











  • @RoVo that suggestion doesn't make any sense at all. Why would you want head when you're processing part of a single filename?

    – roaima
    May 24 '18 at 15:10











  • Instead $(cut -d"-" -f1 $file | head -1) I'd use $(head -n 1 $file | cut -d"-" -f1) to avoid cutting all lines of the file (don't know how big the files are, maybe they are many gigabytes....). OR will it the unix magic stop the function anyways after head -1 ? If so, I' m definately wrong! But this for sure: better use head -n1 instead of deprecated head -1.

    – RoVo
    May 24 '18 at 15:12


















1















I have a bunch of files which all have a first line being a date. All of them start with the same first 2 letters being "ff". I need to create a script which would use that first line in all files and sort them in directories creating these directories as well.



For example 1 file contains that:



Cat file



I need to extract the full date moving all files into directories for year then sub directories for month and another sub for day. So far I have this script which only moves files by year. I was told that I could use -p function, but really I have been using UNIX for 3 days so got confused now.



script










share|improve this question




















  • 2





    Please don't post pictures of text. Copy and paste the text instead. This makes it far easier to read - and for us to copy and test.

    – roaima
    May 24 '18 at 14:28













  • 1. Don't use for file in $(ls ff*) but use for file ff* instead. 2. Put your $variables into double quotes. For example mkdir "$test" instead of just mkdir $test. You will get an error if you try to create a directory that already exists. You can protect against that, or tell mkdir not to worry if it already exists with mkdir -p "$test". 3. In your first screenshot I can see only one file with a name starting with ff. 4. If the file starts with ff (line 7) it can't begin with a year (line 9).. Are you sure your requirements are correct?

    – roaima
    May 24 '18 at 14:36













  • @roaima meant for file in ff* I guess. And you should place head before cut for better performance.

    – RoVo
    May 24 '18 at 14:51











  • @RoVo that suggestion doesn't make any sense at all. Why would you want head when you're processing part of a single filename?

    – roaima
    May 24 '18 at 15:10











  • Instead $(cut -d"-" -f1 $file | head -1) I'd use $(head -n 1 $file | cut -d"-" -f1) to avoid cutting all lines of the file (don't know how big the files are, maybe they are many gigabytes....). OR will it the unix magic stop the function anyways after head -1 ? If so, I' m definately wrong! But this for sure: better use head -n1 instead of deprecated head -1.

    – RoVo
    May 24 '18 at 15:12
















1












1








1


1






I have a bunch of files which all have a first line being a date. All of them start with the same first 2 letters being "ff". I need to create a script which would use that first line in all files and sort them in directories creating these directories as well.



For example 1 file contains that:



Cat file



I need to extract the full date moving all files into directories for year then sub directories for month and another sub for day. So far I have this script which only moves files by year. I was told that I could use -p function, but really I have been using UNIX for 3 days so got confused now.



script










share|improve this question
















I have a bunch of files which all have a first line being a date. All of them start with the same first 2 letters being "ff". I need to create a script which would use that first line in all files and sort them in directories creating these directories as well.



For example 1 file contains that:



Cat file



I need to extract the full date moving all files into directories for year then sub directories for month and another sub for day. So far I have this script which only moves files by year. I was told that I could use -p function, but really I have been using UNIX for 3 days so got confused now.



script







mv vi for mkdir






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 11 at 11:29









Kusalananda

124k16234385




124k16234385










asked May 24 '18 at 13:58









MantasMantas

61




61








  • 2





    Please don't post pictures of text. Copy and paste the text instead. This makes it far easier to read - and for us to copy and test.

    – roaima
    May 24 '18 at 14:28













  • 1. Don't use for file in $(ls ff*) but use for file ff* instead. 2. Put your $variables into double quotes. For example mkdir "$test" instead of just mkdir $test. You will get an error if you try to create a directory that already exists. You can protect against that, or tell mkdir not to worry if it already exists with mkdir -p "$test". 3. In your first screenshot I can see only one file with a name starting with ff. 4. If the file starts with ff (line 7) it can't begin with a year (line 9).. Are you sure your requirements are correct?

    – roaima
    May 24 '18 at 14:36













  • @roaima meant for file in ff* I guess. And you should place head before cut for better performance.

    – RoVo
    May 24 '18 at 14:51











  • @RoVo that suggestion doesn't make any sense at all. Why would you want head when you're processing part of a single filename?

    – roaima
    May 24 '18 at 15:10











  • Instead $(cut -d"-" -f1 $file | head -1) I'd use $(head -n 1 $file | cut -d"-" -f1) to avoid cutting all lines of the file (don't know how big the files are, maybe they are many gigabytes....). OR will it the unix magic stop the function anyways after head -1 ? If so, I' m definately wrong! But this for sure: better use head -n1 instead of deprecated head -1.

    – RoVo
    May 24 '18 at 15:12
















  • 2





    Please don't post pictures of text. Copy and paste the text instead. This makes it far easier to read - and for us to copy and test.

    – roaima
    May 24 '18 at 14:28













  • 1. Don't use for file in $(ls ff*) but use for file ff* instead. 2. Put your $variables into double quotes. For example mkdir "$test" instead of just mkdir $test. You will get an error if you try to create a directory that already exists. You can protect against that, or tell mkdir not to worry if it already exists with mkdir -p "$test". 3. In your first screenshot I can see only one file with a name starting with ff. 4. If the file starts with ff (line 7) it can't begin with a year (line 9).. Are you sure your requirements are correct?

    – roaima
    May 24 '18 at 14:36













  • @roaima meant for file in ff* I guess. And you should place head before cut for better performance.

    – RoVo
    May 24 '18 at 14:51











  • @RoVo that suggestion doesn't make any sense at all. Why would you want head when you're processing part of a single filename?

    – roaima
    May 24 '18 at 15:10











  • Instead $(cut -d"-" -f1 $file | head -1) I'd use $(head -n 1 $file | cut -d"-" -f1) to avoid cutting all lines of the file (don't know how big the files are, maybe they are many gigabytes....). OR will it the unix magic stop the function anyways after head -1 ? If so, I' m definately wrong! But this for sure: better use head -n1 instead of deprecated head -1.

    – RoVo
    May 24 '18 at 15:12










2




2





Please don't post pictures of text. Copy and paste the text instead. This makes it far easier to read - and for us to copy and test.

– roaima
May 24 '18 at 14:28







Please don't post pictures of text. Copy and paste the text instead. This makes it far easier to read - and for us to copy and test.

– roaima
May 24 '18 at 14:28















1. Don't use for file in $(ls ff*) but use for file ff* instead. 2. Put your $variables into double quotes. For example mkdir "$test" instead of just mkdir $test. You will get an error if you try to create a directory that already exists. You can protect against that, or tell mkdir not to worry if it already exists with mkdir -p "$test". 3. In your first screenshot I can see only one file with a name starting with ff. 4. If the file starts with ff (line 7) it can't begin with a year (line 9).. Are you sure your requirements are correct?

– roaima
May 24 '18 at 14:36







1. Don't use for file in $(ls ff*) but use for file ff* instead. 2. Put your $variables into double quotes. For example mkdir "$test" instead of just mkdir $test. You will get an error if you try to create a directory that already exists. You can protect against that, or tell mkdir not to worry if it already exists with mkdir -p "$test". 3. In your first screenshot I can see only one file with a name starting with ff. 4. If the file starts with ff (line 7) it can't begin with a year (line 9).. Are you sure your requirements are correct?

– roaima
May 24 '18 at 14:36















@roaima meant for file in ff* I guess. And you should place head before cut for better performance.

– RoVo
May 24 '18 at 14:51





@roaima meant for file in ff* I guess. And you should place head before cut for better performance.

– RoVo
May 24 '18 at 14:51













@RoVo that suggestion doesn't make any sense at all. Why would you want head when you're processing part of a single filename?

– roaima
May 24 '18 at 15:10





@RoVo that suggestion doesn't make any sense at all. Why would you want head when you're processing part of a single filename?

– roaima
May 24 '18 at 15:10













Instead $(cut -d"-" -f1 $file | head -1) I'd use $(head -n 1 $file | cut -d"-" -f1) to avoid cutting all lines of the file (don't know how big the files are, maybe they are many gigabytes....). OR will it the unix magic stop the function anyways after head -1 ? If so, I' m definately wrong! But this for sure: better use head -n1 instead of deprecated head -1.

– RoVo
May 24 '18 at 15:12







Instead $(cut -d"-" -f1 $file | head -1) I'd use $(head -n 1 $file | cut -d"-" -f1) to avoid cutting all lines of the file (don't know how big the files are, maybe they are many gigabytes....). OR will it the unix magic stop the function anyways after head -1 ? If so, I' m definately wrong! But this for sure: better use head -n1 instead of deprecated head -1.

– RoVo
May 24 '18 at 15:12












2 Answers
2






active

oldest

votes


















0














you should read the man pages:




  • man 1 cut

  • man 1 mkdir


Hints:





  • cut -f1,2,3 gives you the ability to output multiple fields


  • cut --output-delimiter=CHAR lets you override the output-delimiter, which defaults to the input delimiter


  • mkdir -p a/b/c creates the directory hierarchy a/b/c, i.e. b is subdir of a and c is subdir of b.






share|improve this answer































    0














    Here is a solution:



    outputPath='/path/to/output/'
    for file in $(find ~/filesToSort/ -type f -name "ff*")
    do
    firstLine=$(head -n 1 $file)
    datePath="${firstLine//-//}"
    mkdir -p $outputPath$datePath
    mv $file $outputPath$datePath
    done


    Basically,this scripts does:




    1. List all files

    2. Get first line of file into a string

    3. Replace "-" with "/" in string to create a path

    4. Create the path

    5. Move the file to the newly create path


    You may want to add test to be sure that the first line match the required template.






    share|improve this answer























      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%2f445759%2fhow-to-create-a-script-to-make-a-structure-and-sort-files-by-moving-them-into-di%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      0














      you should read the man pages:




      • man 1 cut

      • man 1 mkdir


      Hints:





      • cut -f1,2,3 gives you the ability to output multiple fields


      • cut --output-delimiter=CHAR lets you override the output-delimiter, which defaults to the input delimiter


      • mkdir -p a/b/c creates the directory hierarchy a/b/c, i.e. b is subdir of a and c is subdir of b.






      share|improve this answer




























        0














        you should read the man pages:




        • man 1 cut

        • man 1 mkdir


        Hints:





        • cut -f1,2,3 gives you the ability to output multiple fields


        • cut --output-delimiter=CHAR lets you override the output-delimiter, which defaults to the input delimiter


        • mkdir -p a/b/c creates the directory hierarchy a/b/c, i.e. b is subdir of a and c is subdir of b.






        share|improve this answer


























          0












          0








          0







          you should read the man pages:




          • man 1 cut

          • man 1 mkdir


          Hints:





          • cut -f1,2,3 gives you the ability to output multiple fields


          • cut --output-delimiter=CHAR lets you override the output-delimiter, which defaults to the input delimiter


          • mkdir -p a/b/c creates the directory hierarchy a/b/c, i.e. b is subdir of a and c is subdir of b.






          share|improve this answer













          you should read the man pages:




          • man 1 cut

          • man 1 mkdir


          Hints:





          • cut -f1,2,3 gives you the ability to output multiple fields


          • cut --output-delimiter=CHAR lets you override the output-delimiter, which defaults to the input delimiter


          • mkdir -p a/b/c creates the directory hierarchy a/b/c, i.e. b is subdir of a and c is subdir of b.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered May 24 '18 at 14:50









          oxdecaoxdeca

          11




          11

























              0














              Here is a solution:



              outputPath='/path/to/output/'
              for file in $(find ~/filesToSort/ -type f -name "ff*")
              do
              firstLine=$(head -n 1 $file)
              datePath="${firstLine//-//}"
              mkdir -p $outputPath$datePath
              mv $file $outputPath$datePath
              done


              Basically,this scripts does:




              1. List all files

              2. Get first line of file into a string

              3. Replace "-" with "/" in string to create a path

              4. Create the path

              5. Move the file to the newly create path


              You may want to add test to be sure that the first line match the required template.






              share|improve this answer




























                0














                Here is a solution:



                outputPath='/path/to/output/'
                for file in $(find ~/filesToSort/ -type f -name "ff*")
                do
                firstLine=$(head -n 1 $file)
                datePath="${firstLine//-//}"
                mkdir -p $outputPath$datePath
                mv $file $outputPath$datePath
                done


                Basically,this scripts does:




                1. List all files

                2. Get first line of file into a string

                3. Replace "-" with "/" in string to create a path

                4. Create the path

                5. Move the file to the newly create path


                You may want to add test to be sure that the first line match the required template.






                share|improve this answer


























                  0












                  0








                  0







                  Here is a solution:



                  outputPath='/path/to/output/'
                  for file in $(find ~/filesToSort/ -type f -name "ff*")
                  do
                  firstLine=$(head -n 1 $file)
                  datePath="${firstLine//-//}"
                  mkdir -p $outputPath$datePath
                  mv $file $outputPath$datePath
                  done


                  Basically,this scripts does:




                  1. List all files

                  2. Get first line of file into a string

                  3. Replace "-" with "/" in string to create a path

                  4. Create the path

                  5. Move the file to the newly create path


                  You may want to add test to be sure that the first line match the required template.






                  share|improve this answer













                  Here is a solution:



                  outputPath='/path/to/output/'
                  for file in $(find ~/filesToSort/ -type f -name "ff*")
                  do
                  firstLine=$(head -n 1 $file)
                  datePath="${firstLine//-//}"
                  mkdir -p $outputPath$datePath
                  mv $file $outputPath$datePath
                  done


                  Basically,this scripts does:




                  1. List all files

                  2. Get first line of file into a string

                  3. Replace "-" with "/" in string to create a path

                  4. Create the path

                  5. Move the file to the newly create path


                  You may want to add test to be sure that the first line match the required template.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered May 24 '18 at 15:29









                  Kevin LemaireKevin Lemaire

                  1,170624




                  1,170624






























                      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%2f445759%2fhow-to-create-a-script-to-make-a-structure-and-sort-files-by-moving-them-into-di%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?