如何在 Linux 下使用命令行组织相应名称目录中的文件

如何在 Linux 下使用命令行组织相应名称目录中的文件

我有一个目录,里面装满了各种文件,这些文件的名称不同(即没有使用特定模式命名)且具有不同的扩展名,我想将每个文件放在以每个文件命名的新创建的子目录中;在 Linux 下从命令行实现此目的的最佳方法是什么?
这听起来有点令人困惑,让我举个例子:让我们在目录中随机调用一个文件./filename.ext,我想将其放在一个名为的子目录中./filename,这样新路径实际上就是./filename/filename.ext

我按照以下步骤进行了一些尝试:

  • 我在测试目录中创建了一些测试文件,从file-1.txtfile-9.txtfor num in {1..9}; do touch file-$num.txt; done
  • 我创建了一个以每个文件名命名的目录for name in $(eval ls | cut -b 1-6); do mkdir $name; done
  • 我已将源文件移动到各自的目录中for name in $(eval ls | grep -e ".txt" | cut -b 1-6); do mv $name.txt $name/$name.txt; done

如您所见,此解决方案有效,但它的巨大缺点是它只在这种情况下有效,即文件名长度和扩展名完全相同的文件。如果我有一些文件的名称和扩展名不同,那么这根本没用。cut我想,使用命令在这里不是理想的解决方案,但目前我还没有找到更好的方法。

作为奖励,如果能找到一种在移动/重命名文件时自动创建子目录的方法,而无需mkdir先前使用(因此当我ls实际重命名时,不必担心排除新创建的目录),那就太酷了;但最终这是一个次要问题。

答案1

我想你的问题的解决方案叫做参数替换(看看详细说明)。给定一个文件的名称,filename您将使用 获得其扩展名${filename##*.},并使用 获得不带扩展名的名称${filename%.*}

也就是说,您可能需要修改for循环,例如:

# for all (*) files in the current directory
for i in *;
do
    # -f checks if it is a file (skip directories)
    [ -f "$i" ] || continue
    # store the file name in filename
    filename=$(basename $i)
    # ext = the extension of the file (here we don't care, jfi)
    ext="${filename##*.}"
    # dir = the file name without its extension
    dir="${filename%.*}"
    # create the directory
    mkdir -p $dir
    # move the file in that directory
    mv $i $dir
done

不幸的是,我没有明白你的意思奖金任务,因此它仍将是一个开放的挑战...:)

答案2

这是一种使用较少 shell 脚本但使用较多命令的方法。

   find -maxdepth 1 -type f > file-list

查找当前目录中的所有文件并保存此列表。

   grep -o '\./.*\.' file-list | sed s/\.$// > dir-list

过滤此列表以仅包含某处带有点的文件名。使用 sed 删除最后一个点,保存此列表。

   mkdir $(<dir-list)

创建所有文件夹。

   sort dir-list > dir-list.s
   sort file-list > file-list.s

这是为了按列出的顺序将文件名与文件夹名称对齐>

   paste file-list dir-list

这看起来不正确,因为文件文件列表将在这里。在我的例子中,还有一个名为随机的. 从文件列表中删除这些名称。

   sed -E '/^\.\/(random|file-list)$/d' -i file-list
   sort file-list > file-list.s

再次调查以下命令的输出:粘贴文件列表目录列表

它看起来应该是这样的:

   ./CCrtWW].GdH   ./CCrtWW]
   ./c[ifzJlKnEYXO.wXF ./c[ifzJlKnEYXO
   ./FAEhz.u[A ./FAEhz
   ./FGMlrKcJHF.pHp    ./FGMlrKcJHF
   ./HGxKPWZK.MpK  ./HGxKPWZK
   ./JxwNrN.zoj    ./JxwNrN

一旦看起来正确,就从列表中创建一个 shell 脚本并将其发布:

 paste file-list dir-list | sed 's/^/mv -v /' | sh

相关内容