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.

8
  • how about visualizing your issue? (for ex. tree <your dir>) Commented Feb 6, 2018 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. Commented Feb 6, 2018 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? Commented Feb 6, 2018 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. Commented Feb 6, 2018 at 20:22
  • 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. Commented Feb 6, 2018 at 20:36

2 Answers 2

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.

2
-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
6
  • this keeps the full file name intead of desiredname.m :) no ? -- & test the directory is present is mush better than removing error messages by redirection to /dev/null :) Commented Feb 6, 2018 at 19:57
  • @francoisP I'm eagerly awaiting your solution. The OP did not request to alter the filenames. I hope the downvote had a valid excuse. Commented Feb 6, 2018 at 20:15
  • 1
    I didn’t vote, but see Why is looping over find’s output bad practice? Also, we prefer answers with explanations. Commented Feb 6, 2018 at 21:04
  • Yeah, my bad for not being clear. Thanks anyway for the help! Commented Feb 6, 2018 at 22:13
  • I down-voted because like G-Man said this is bad practice. Also you have not quoted some variables. Commented Feb 6, 2018 at 22:26

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.