10

I have parent folder and inside this folder I have 4 files

ParentFolder
      File1.txt
      File2.txt
      File3.txt
      File4.txt

I wanted to create subfolders inside the parent folder and carry the name of the files then move every file inside the folder that carry it is name like:

ParentFolder
    File1          
      File1.txt
    File2          
      File2.txt
    File3          
      File3.txt
    File4          
      File4.txt

How can I do that in batch or tsch script? I tried this script:

#!/bin/bash
in=path_to_my_parentFolder
for i in $(cat ${in}/all.txt); do
cd ${in}/${i} 
ls > files.txt
for ii in $(cat files.txt); do
mkdir ${ii}
mv ${ii} ${in}/${i}/${ii} 
done     
done
  • Were this bash, one could easily try: 'for Q in *.txt;do Z="${Q%.txt}";mkdir "$Z" && mv "$Q" "$Z";done' but tsch? that awaits the last remaining living tsch guru – Theophrastus Aug 03 '15 at 20:05

3 Answers3

22

You're overcomplicating this. I don't understand what you're trying to do with all.txt. To enumerate the files in a directory, don't call ls: that's more complex and doesn't work reliably anyway. Use a wildcard pattern.

To strip the extension (.txt) at the end of the file name, use the suffix stripping feature of variable substitution. Always put double quotes around variable substitutions.

cd ParentFolder
for x in ./*.txt; do
  mkdir "${x%.*}" && mv "$x" "${x%.*}"
done
  • This was actually very useful for me to organize my investments and it's redemptions in each folder, many thanks. every question answered saves me time to not having to create the solution myself :D – lauksas Feb 15 '20 at 17:55
  • One minor detail: for "./*.txt" ${x%.*} will output "./File1", "./File2" etc. with leading "./". Use "*.txt" instead "./*.txt" to just get "File1", "File2" without leading "./" – Christoph Feb 06 '22 at 20:50
  • I have used and got empty folders lost all my movie files :(( Why have my files been deleted? (I had just two $ ) for x in ./.mkv; do mkdir "${x%.}" && mv "$x" "$${x%.*}" done – Shahram Shinshaawh Jul 05 '23 at 21:08
4

Instead of loop you can use find

find ParentFolder/* -prune -type f -exec \
  sh -c 'mkdir -p "${0%.*}" && mv "$0" "${0%.*}"' {} \;
Costas
  • 14,916
0

Or you could really make it simple. Use basename, part of coreutils.

cd ParentFolder &&
for i in ./*.txt 
 do   
    d=$(basename "$i" .txt)   
    mkdir "$d" && mv "$i" "$d" 
 done
Allen
  • 101