1

As an example, I have a directory with multiple files in this general format:

dir1/identifier1_desiredName1.m
dir1/identifier1_desiredName2
dir1/identifier1_desiredName3.m
dir1/identifier2_desiredName1.m
dir1/identifier2_desiredName2.m
dir1/identifier3_desiredName1.m
dir1/identifier3_desiredName2.m
dir1/identifier3_desiredName3
dir1/identifier4_desiredName1.m
dir1/identifier4_desiredName2.m
dir1/jabberwocky-mimsy-borogoves
dir1/other--should-not-be-moved

I'm trying to come up with a script that separates the files by the identifier by making a directory using that identifier, and then move files with the same identifier into that directory.

By the end of the moving, I would like to have something like:

dir1/identifier1/desiredName1.m
dir1/identifier1/desiredName2
dir1/identifier1/desiredName3.m
dir1/identifier2/desiredName1.m
dir1/identifier2/desiredName2.m
dir1/identifier3/desiredName1.m
dir1/identifier3/desiredName2.m
dir1/identifier3/desiredName3
dir1/identifier4/desiredName1.m
dir1/identifier4/desiredName2.m
dir1/jabberwocky-mimsy-borogoves
dir1/other--should-not-be-moved

As of right now, I think that I'm on the right track for the directory making:

awk _ {print $1} | uniq | mkdir

Syntax probably isn't quite correct, but the general idea is to print out the first column, separated by _, omitting repeats, and then piping those names into mkdir. But then I'm at a loss for moving the files into the directories. I was thinking about using grep similarly (replacing mkdir above and then piping into mv), but I wasn't sure if it would work.

  • how about visualizing your issue? (for ex. tree <your dir>) – RomanPerekhrest Feb 06 '18 at 18:52
  • 2
    As Roman says, please provide a short (i.e., no more than 17 lines) but illustrative example of what you have and what you want to do. Do not** respond in comments; [edit] your question to make it clearer and more complete. Also, try to solve this yourself and tell us what you tried and what happened. – G-Man Says 'Reinstate Monica' Feb 06 '18 at 18:59
  • I took the liberty of expanding your example to match your description.  If my edit is wrong, fix it — but also fix or clarify your statements “I’ve got *directories* with multiple files” and “Each directory has about 3-5 files with the same identifier and about 150 files total” (now deleted).  But this raises the question: Do you want an identifier1 directory at the top level, or do you want dir1/identifier1 and dir2/identifier1? – G-Man Says 'Reinstate Monica' Feb 06 '18 at 20:16
  • And using a filename of identifier_desiredName.m  is not a very clear way of saying that you want identifier_desiredName.m to be renamed to desiredName.m in the identifier directory. – G-Man Says 'Reinstate Monica' Feb 06 '18 at 20:22
  • @G-Man Where does he ask for renaming the files? – Gerard H. Pille Feb 06 '18 at 20:25
  • 1
    Well, that’s kind-of my point.  By saying identifier_desiredName.m instead of identifier_RestOfName.m, they made francois P and me believe that they wanted the files renamed, and since they don’t show the result they want, they left it ambiguous. – G-Man Says 'Reinstate Monica' Feb 06 '18 at 20:36
  • @G-Man Got you. Let's see if we hear Trailing Penguin again. – Gerard H. Pille Feb 06 '18 at 20:39
  • Yeah, sorry that I'm not being very clear. This is my first post and I honestly wasn't sure how exactly what I wanted because I wasn't sure what I could expect. I actually DO want the files to be renamed, so I'll edit my post to reflect this and give a example of what I would want at as a final product. Thanks for bearing with me! – Trailing Penguin Feb 06 '18 at 21:13

2 Answers2

0

you can list your files in list from ls > list for example
then use a loop-read of it to build sub-folders & then move the files dispatching them in the good one from its name as a pattern filter.

here I made a test from empty files touch filename to demonstrate method

bash-4.4$ while read
> do
> if [ ! -d ${REPLY/_*/} ]; then
>    mkdir ${REPLY/_*/}
> fi
> done < list

bash-4.4$ #here directories are made then use similar method for moving files
bash-4.4$ while read; do  if [ -f $REPLY ] ; then mv $REPLY ${REPLY/_*/}/${REPLY/*_/} ; fi ;  done < list
bash-4.4$ tree
.
├── identifier
│   └── desiredName.m
├── identifier1
│   ├── desirename1.m
│   └── desirename.m
├── identifier2
│   └── desirename2.m
└── list

3 directories, 5 files
bash-4.4$ 5~

You can do direct use in shell or use similar syntax in a script of course.

francois P
  • 1,219
-1
find . -type f -name '*_*.m' | while read FP
do
  FN="${FP##*/}"
  DN="${FP%/*}"
  ID="${FN%_*}"
  echo $FP "=>" $DN "/" $ID "/" $FN
  mkdir "$DN/$ID" 2>/dev/null
  mv "$FP" "$DN/$ID"
done