如何在Linux下通过命令行在相应命名的目录中组织文件


1

我有一个目录,里面充满了各种文件,它们的名称不同(即,没有使用特定的模式命名),并且具有不同的扩展名,我想将每个文件放在以每个文件命名的新创建的子目录中。在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实际重命名时,我不必担心排除新创建的目录) ); 但最终这是第二个问题。

Answers:


2

我猜您问题的解决方案称为参数替换(请参阅详细说明)。给定一个文件名,filename您将使用扩展名,使用${filename##*.}w扩展名${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

不幸的是,我没有意识到您的奖金任务的重点,因此它将仍然是一个公开的挑战... :)


它运行完美,您是否愿意向我解释我已经做了什么:)?
Sekhemty

我刚刚在代码中添加了一些注释。但是正如我所说的,这种技巧称为参数替换,我建议访问我提供的链接,以了解发生了什么:)
binfalse 2013年

1

这是一种使用较少的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

这看起来不正确,因为文件文件列表将在此处。在我的情况下,还有一个名为random的文件。从文件列表中删除这些名称。

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

再次调查以下命令的输出:paste file-list dir-list

它看起来应该像这样:

   ./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

假定文件名中没有空格或其他奇数字符。
ЯрославРахматуллин
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.