0

I have 500000 files in a folder and want to move them to subfolders. These subfolders should be created automatically.

The pattern is {prefix}-{date}T{time}-{suffix}.

The folder structure should look like {date}/{time}/{suffix}.

I have managed to remove the prefix with a bash script:

    #!/bin/bash
    for f in prefix-* ; do
        mv "$f" "${f/prefix-}"
    done
  • 3
    Ok. And what have you done this far? – maulinglawns Nov 22 '16 at 11:04
  • Sorry, i added some code – Martin Schlagnitweit Nov 22 '16 at 11:06
  • Now add directory creation and move files directly to it. – Costas Nov 22 '16 at 11:46
  • But how can i get the folder names {date}? – Martin Schlagnitweit Nov 22 '16 at 11:51
  • 1
    Use sed (better awk) to pick each component: date="$(awk -F'-|T' '{print $1}' <<< "$f" )" (time and suffix are $2 and $3, respectively). The idea is to pass the string (filename) to awk, set T or - as separators (-F option) and then pick the selected field. With this you can create the dirs. – Fiximan Nov 22 '16 at 11:55
2

Assuming the files never have dashes - or uppercase T in the names, you can build the following bash loop:

for f in *
do
   date=$(tmp=${f#*-};echo ${tmp%T*})
   time=$(tmp=${f#*T};echo ${tmp%-*})
   suffix=${f##*-}
   mkdir -p ${date}/${time}/${suffix}
   mv $f ${date}/${time}/${suffix}/
done

This is basic bash parameter expansion syntax, as per the man page:

   ${parameter#word}
   ${parameter##word}
          Remove matching prefix pattern.  The word is expanded to produce a pattern just as in pathname expansion.  If the pat‐
          tern matches the beginning of the value of parameter, then the result of the expansion is the expanded value of param‐
          eter with the shortest matching pattern (the ``#'' case) or the longest matching pattern (the  ``##''  case)  deleted.
          If  parameter is @ or *, the pattern removal operation is applied to each positional parameter in turn, and the expan‐
          sion is the resultant list.  If parameter is an array variable subscripted with @ or *, the pattern removal  operation
          is applied to each member of the array in turn, and the expansion is the resultant list.

   ${parameter%word}
   ${parameter%%word}
          Remove matching suffix pattern.  The word is expanded to produce a pattern just as in pathname expansion.  If the pat‐
          tern matches a trailing portion of the expanded value of parameter, then the result of the expansion is  the  expanded
          value  of  parameter  with  the shortest matching pattern (the ``%'' case) or the longest matching pattern (the ``%%''
          case) deleted.  If parameter is @ or *, the pattern removal operation is applied to each positional parameter in turn,
          and  the  expansion  is  the  resultant  list.  If parameter is an array variable subscripted with @ or *, the pattern
          removal operation is applied to each member of the array in turn, and the expansion is the resultant list.

I have used a temporary variable as placeholder, since bash won't allow for direct nesting of the expansion op.

date=$(tmp=${f#*-};echo ${tmp%T*})
$f is the current file name
tmp={f#*-} : remove everything up to and including the FIRST -
At this point tmp holds {date}T{time}-{suffix}
${tmp%T*} : remove everything after T (inclusive)

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.