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.


  • 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.
    – pLumo
    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.
    – pLumo
    May 24 '18 at 15:12

you should read the man pages:

  • man 1 cut
  • man 1 mkdir


  • 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.

Here is a solution:

for file in $(find ~/filesToSort/ -type f -name "ff*")
    firstLine=$(head -n 1 $file)
    mkdir -p $outputPath$datePath
    mv $file $outputPath$datePath

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.