【问题标题】:move files to a subdirectory based on filename with spaces根据带空格的文件名将文件移动到子目录
【发布时间】:2018-09-20 17:06:50
【问题描述】:

此脚本的目标是根据文件名内容创建一个目录。文件名如下所示:

  • "foo-foo bar-bar-bar1 5644.jpg"
  • "foo-foo bar-bar-bar1 5648.jpg" >> /foo-foo bar-bar-bar1
  • "foo-foo bar-bar-bar2 7644.jpg"
  • "foo-foo bar-bar-bar2 7648.jpg" >> /foo-foo bar-bar-bar2

我希望能够为目录中的所有文件创建一个名为“foo-foo bar-bar-bar1”的文件夹,依此类推。 (要创建数百个目录)并将所有具有该扩展名的文件放入其中。

问题是文件扩展名之间有空格而不是“_”。而且,一些文件名之间有多个空格。 我该如何着手解决这个问题?如果有帮助,我正在使用 Mac。

【问题讨论】:

  • 对于有多个空格的文件名,是否总是移动到最后一个空格前所有字符组成的目录名?
  • 是的!很抱歉没有正确地提出我的问题。也许我的想法也错了。我正在寻找文件扩展名的这一部分作为变量:> foo-foo bar-bar-bar1a > foo-foo arb-arb- arb1d > foo-foo abr-abr-abr1e 我需要 extension-2,它是随机的,移动到基于“extension-1 extension-2”的目录中。第三部分对组织没有意义。

标签: linux bash macos command-line terminal


【解决方案1】:

这就是答案! @david-c-rankin 这行得通。谢谢你帮助我。

while read file; do
    fname="${file##*/}"   ## strip path information, leaving filename
    dname="${fname% *}"   ## get all chars before the last space
    dname="${dname%%* }"  ## trim ext 3 from filename
    mkdir -p "$dname"     ## create the directory (no error if it exists)
                          #  (add -i to be prompted if dir exists)
    mv -i "$file" "$dname"   ## move the file to the new directory
done < <(find . -type f -name "*.txt")

【讨论】:

  • 如果文件的第二个和第三个扩展名之间有多个空格会怎样?脚本失败并返回此错误mkdir: cannot create directory ‘’: No such file or directory mv: cannot move './cc-19 11-12-r3 4482.txt' to '': No such file or directory
  • 逻辑保持不变,但您需要进行更多验证。如果文件名中可以​​有任意数量的空格。我会将文件名的所有部分读入一个数组,例如declare -a array; 然后去掉dname="${dname%%* }",然后是idx=0; tmp="$dname"; while :; do array[$idx]="${tmp%% *}"; tmp="${tmp#* }"; ((idx++)); [ "${array[$((idx-1))]}" = "$tmp" ] &amp;&amp; break; done 然后你就知道片数(例如${#array[@]})所以你用你想要的片作为目录名。
【解决方案2】:

您的问题有点不清楚您的目录名称是否由 last 空格之前的所有字符组成,您的评论有所帮助,但 extension-1extension-2的解释还是有点不确定,不过我觉得我们在沟通。

要根据文件名中包含的所有内容创建一个目录,直到最后一个空格,您可以使用简单的带有子字符串删除的参数扩展。例如,要删除右侧的所有内容,直到(包括)最后一个空格,您可以使用dname="${file% *}"(其中dname 是要将文件移动到的结果目录名称)。示例:

file="foo-foo bar-bar-bar1 5648.jpg"
dname="${file% *}"

现在dname 包含:"foo-foo bar-bar-bar1"

(注意: 使用#左侧修剪% 从右侧修剪的参数扩展。## 从左,而# 只修剪到第一次出现。% 从相反的方向以相同的方式工作)

然后只需将文件移动到dname,您可以使用进程替换(使用find 命令搜索当前目录下的所有.jpg 文件,并创建新集提供的目录中的目录以及一个简单的:

while read file; do
    fname="${file##*/}"   ## strip path information, leaving filename
    dname="${fname% *}"   ## get all chars before the last space
    mkdir -p "$dname"     ## create the directory (no error if it exists)
                          #  (add -i to be prompted if dir exists)
    mv "$file" "$dname"   ## move the file to the new directory
done < <(find . -type f -name "*.jpg")

您可以附加到dname(或进一步解析解析file)以将目录放在当前目录以外的位置。

另请注意,如果您想进一步解析文件名,以便移动的文件是 "5648.jpg" 而不是完整的 "foo-foo bar-bar-bar1 5648.jpg",您只需使用类似于以下内容的内容:

finalname="${fname##* }"

那么你的动作是:

mv "$file" "$dname/$finalname"

如果您有任何问题,请告诉我。


使用最后一个空格分隔段作为目录名称 (ext-2)

如果我们将"cc-19 a-18-1a 6790.jpg" 移动到"a-18-1a" 目录,那么你对find 返回的文件名的一系列解析如下:

while read file; do
    fname="${file##*/}"   ## strip path information, leaving filename
    dname="${fname% *}"   ## get all chars before the last space
    dname="${dname##* }"  ## trim ext-1, leaving ext-2
    mkdir -p "$dname"     ## create the directory (no error if it exists)
                          #  (add -i to be prompted if dir exists)
    mv "$file" "$dname"   ## move the file to the new directory
done < <(find . -type f -name "*.jpg")

这会将"cc-19 a-18-1a 6790.jpg" 移动到"./a-18-1a"

如果您仍然存在沟通问题,请再发表评论。

【讨论】:

  • 看起来不错,虽然我建议使用mv -i 来避免在发生奇怪的事情并且存在名称冲突时覆盖文件。还有一个@JasonB11 的问题:是否应该将名为“foo-foo bar-bar-bar1 5644.jpg”的文件移动到名为“foo-foo bar-bar-bar1”的目录且其名称保持不变,或者重命名只是“5644.jpg”?
  • 我们的想法是一样的——我会用-i更新。
  • 另一件事:这根本无法处理没有空格的文件名(它会尝试创建与文件同名的目录)。 @JasonB11 的另一个问题是:它应该对这个目录中的所有 .jpg 文件和所有子目录 进行操作,还是只对这个目录中“就在这里”的那些文件进行操作。
  • 第二个空格前的“第二个扩展名”是目录的命名方式。\s\s -/foo-foo bar-bar-bar1
  • 这是一个很好的观点。他解释说,这些文件都有由spaces 而不是'_' 分隔的扩展名,所以这就是目标。但是如果文件名没有空格,那么他需要在第二次键入'.',以确保目录和文件名相同时不会出现一堆错误......
猜你喜欢
  • 2014-06-06
  • 2021-07-12
  • 1970-01-01
  • 1970-01-01
  • 2019-01-02
  • 1970-01-01
  • 2016-03-21
  • 2023-04-10
  • 1970-01-01
相关资源
最近更新 更多