使用包含的文件名替换文件夹名称

使用包含的文件名替换文件夹名称

我有一千多个文件夹,这些文件夹的名称都是随机的。每个文件夹至少有一个文件,扩展名为 avi、mkv、srt 或 mp4。
我打算用随机生成的文件夹名称(不带扩展名)替换它所包含的第一个文件名。顺便说一下,文件名中包括 () - 和其他奇怪的字符。我认为,该脚本应该:

  1. 进入文件夹
  2. 获取不带扩展名的名字
  3. 退出文件夹
  4. 使用新名称重命名文件夹
  5. 递归遍历文件夹,因为它可能包含其他子文件夹

不过,第 5 步可能会被覆盖。
由于我是 Bash 编程方面的书呆子,因此我非常感激有人能帮我。有人能帮忙吗?

答案1

鉴于

$ tree
.
├── eYRlzR8Ibk
│   ├── Awnluslskl
│   │   └── ö, û, accnts.avi
│   ├── baz
│   └── xyz.mp4
└── wHKEWxFgIt
    └── foo bar.srt

3 directories, 4 files

然后

$ find . -mindepth 1 -depth -type d -execdir sh -c '
  for d; do
    set -- "$d"/*.*
    [ -e "$1" ] || continue
    f="${1##*/}"
    mv -n -- "$d" "${f%.*}"
  done
' sh {} +

导致

$ tree
.
├── foo bar
│   └── foo bar.srt
└── xyz
    ├── baz
    ├── ö, û, accnts
    │   └── ö, û, accnts.avi
    └── xyz.mp4

3 directories, 4 files

答案2

脚本 复制/粘贴脚本到文本编辑器中用包含所有带文件的目录名
替换~/test/testfolders3变量 无需先试一下,看看会发生什么。 编辑后,您可以从文本编辑器中复制它并将其粘贴到终端窗口中。sourcedir
mv $oldname $newname

sourcedir=~/test/testfolders3
cd $sourcedir
files=$(find . -type f)
for f in $files
  do
    echo -e "0:Not modified file name:\t $f"
    bname=$(basename $f)                             # Get file's name without path to it
    filewe=$(echo $bname | sed 's/\.[^.]*$//')       # Get file's name without extension
    echo -e "1:Filename without extension:\t $filewe"
    dir=$(dirname $f)                                # Get directory name where file is located
    echo -e "2:Parent file's directory:\t $dir"
    parfold=$(echo $(dirname $dir) | sed 's/.\///')  # Get file's parent directory's parent directory name with stripped `./` preffix
    echo -e "3:Parent-parent stripped dir:\t $parfold"
    olddir=$(echo $dir | sed 's@.*/@@')              # Get file's parent directory name without path to it (everything before the last `/` slash is stripped)
    oldname=$sourcedir/$parfold/$olddir              # Get current file's parent directory name with full path
    echo -e "4:Old folder name:\t\t $oldname"; 
    newname=$sourcedir/$parfold/$filewe              # Set new file's parrent directory name with full path
    echo -e "5:New folder name:\t\t $newname"
    mv $oldname $newname                             # Renames folders
  done
find $sourcedir -type f                              # Shows result

抱歉,如果它没有完全优化。我不是程序员。它只是我找到的不同答案的汇编。这花了很多时间,因为我不经常这样做。

它现在不检查目录是否存在。因此,使用第一个移动文件的名称重命名一次后,它只会抛出一条如下消息:

mv: cannot stat '/home/user/test/testfolders3/folders/lkjskd': No such file or directory

第一个移动的文件并不意味着按字母顺序排列的第一个文件。

find $sourcedir -type f命令执行结果如下:

/home/user/test/testfolders3/folders3/file3/file3.mp4
/home/user/test/testfolders3/folders3/file1/file1.avi
/home/user/test/testfolders3/folders3/file2/file2.mkv
/home/user/test/testfolders3/folders3/folders/file3/file3.mp4
/home/user/test/testfolders3/folders3/folders/file1/file1.avi
/home/user/test/testfolders3/folders3/folders/file2/file2.mkv
/home/user/test/testfolders3/folders2/soft/soft.ware
/home/user/test/testfolders3/folders2/soft/file1.avi
/home/user/test/testfolders3/folders2/inter/inter.pol
/home/user/test/testfolders3/folders2/inter/file3.mp4
/home/user/test/testfolders3/folders2/file2/file2.mkv
/home/user/test/testfolders3/folders2/file2/ser.seg
/home/user/test/testfolders3/folders2/folders/file3/file3.mp4
/home/user/test/testfolders3/folders2/folders/file1/file1.avi
/home/user/test/testfolders3/folders2/folders/file2/file2.mkv
/home/user/test/testfolders3/folders/kata/kata.ptx
/home/user/test/testfolders3/folders/kata/file1.avi
/home/user/test/testfolders3/folders/sinaps/sinaps.rtf
/home/user/test/testfolders3/folders/sinaps/file3.mp4
/home/user/test/testfolders3/folders/file2/file2.mkv
/home/user/test/testfolders3/folders/file2/tema.txt
/home/user/test/testfolders3/folders/file2/fan.in

以前的文件夹名称:

/home/user/test/testfolders3/folders3/kjakd/file2.mkv
/home/user/test/testfolders3/folders3/jafklsjdkl/file1.avi
/home/user/test/testfolders3/folders3/folders/kjakd/file2.mkv
/home/user/test/testfolders3/folders3/folders/jafklsjdkl/file1.avi
/home/user/test/testfolders3/folders3/folders/lkjskd/file3.mp4
/home/user/test/testfolders3/folders3/lkjskd/file3.mp4
/home/user/test/testfolders3/folders2/kjakd/file2.mkv
/home/user/test/testfolders3/folders2/kjakd/ser.seg
/home/user/test/testfolders3/folders2/jafklsjdkl/soft.ware
/home/user/test/testfolders3/folders2/jafklsjdkl/file1.avi
/home/user/test/testfolders3/folders2/folders/kjakd/file2.mkv
/home/user/test/testfolders3/folders2/folders/jafklsjdkl/file1.avi
/home/user/test/testfolders3/folders2/folders/lkjskd/file3.mp4
/home/user/test/testfolders3/folders2/lkjskd/inter.pol
/home/user/test/testfolders3/folders2/lkjskd/file3.mp4
/home/user/test/testfolders3/folders/kjakd/file2.mkv
/home/user/test/testfolders3/folders/kjakd/tema.txt
/home/user/test/testfolders3/folders/kjakd/fan.in
/home/user/test/testfolders3/folders/jafklsjdkl/kata.ptx
/home/user/test/testfolders3/folders/jafklsjdkl/file1.avi
/home/user/test/testfolders3/folders/lkjskd/sinaps.rtf
/home/user/test/testfolders3/folders/lkjskd/file3.mp4

答案3

Steelworker 提出的解决方案(见上文)运行完美、快速且流畅。代码非常简洁。你们太棒了。感谢你们的时间和奉献。致以最诚挚的问候。

相关内容