【问题标题】:Copy specific files from subdirectories into one directory将特定文件从子目录复制到一个目录
【发布时间】:2019-12-08 20:53:20
【问题描述】:

我有一个目录:

❯ find ./images -name *150x150.jpg
./images/2060511653921052666.images/thumb-150x150.jpg
./images/1777759401031970571.images/thumb-150x150.jpg
./images/1901716489977597520.images/thumb-150x150.jpg
./images/2008758225324557620.images/thumb-150x150.jpg
./images/1988762968386208381.images/thumb-150x150.jpg
./images/1802341648716075239.images/thumb-150x150.jpg
./images/2051017760380879322.images/thumb-150x150.jpg
./images/1974813836146304123.images/thumb-150x150.jpg
./images/2003120002653201215.images/thumb-150x150.jpg
./images/1911925394312129508.images/thumb-150x150.jpg
(...)

我想将所有这些文件 (thumb-150x150.jpg) 复制到一个目录中。

❯ find ./images -name *150x150.jpg -exec cp {} ./another-directory \;

当然,每个文件都会被下一个文件覆盖。

那么我怎样才能将它们复制到:

1) 1.jpg2.jpg3.jpg...等

2) 使用子目录 id (./images/2060511653921052666.images/thumb-150x150.jpg) 作为目标文件名(本例中为2060511653921052666.jpg)?

【问题讨论】:

  • 每个文件显然都需要一个新的/不同的名称;虽然 SO 社区可以提出很长的新名称/格式列表,但最终新名称的格式由您决定;您打算在未来如何参考/使用这些文件?您是否需要对新文件名应用任何类型的排序?您是否需要根据特定模式搜索/列出文件的能力?新文件名是否应该包含任何信息来说明它最初来自哪里?该文件是否需要关联/引用其他目录或文件?
  • 文件名必须不同 - 仅此而已。我不需要引用特定文件。我只需要将它们全部放在一个位置(文件夹)。
  • @gib :为什么不简单地命名文件,即2060511653921052666-thumb-150x150.jpg。然后,您可以将它们全部放入同一个目录中,仍然可以查看它们的来源?

标签: bash file copy zsh file-copying


【解决方案1】:

一个简单的 bash 脚本,使用 $RANDOM 为每个复制的图像生成一个随机数。每个文件的新名称中都嵌入了一个随机数。

请注意,$RANDOM 生成一个介于 1 和 32767 之间的随机数。因此可以多次生成相同的随机数。仅当您要复制数万张图像时才有可能发生这种情况。

提高每个生成数字的随机性是相当容易的。

# !/bin/bash
cd images
for d in *
do
    [ -d $d ] && cd $d
    for image in *150x150.jpg
    do
        cp -pv $image /another-dir/thumb${RANDOM}.jpg
    done
    [ -d $d ] && cd ..
done

【讨论】:

    【解决方案2】:

    你可以使用循环:

    i=1
    find ./images -name *150x150.jpg | while read line; do
            cp $line /anotherdir/$i.jpg
            i=$[i+1]
    done
    

    【讨论】:

    • i=$[i+1] 替换为((i++))
    【解决方案3】:

    如果你有 GNU 并行,这是可能的:

    find ./images -name *150x150.jpg | \
    parallel 'mv {} ./another-directory/`stat -c%i {}`_{/}'
    

    stat -c%i {} 获取每个文件的 inode

    我在我的系统上测试了下面的命令:

    find -iname "*.mp3" | parallel 'cp {} ~/tmp/{/.}_`stat -c%i {}`.mp3'
    
    {/} .......... gets just the filename with no full path "basename"
    {.} .......... removes extension
    

    在运行实际命令之前,您可以在 cp 或 mv 前面放置 echo 命令以测试您的命令。

    来源:https://stackoverflow.com/a/16074963/2571881

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-18
      • 2019-11-01
      • 1970-01-01
      • 2012-02-15
      • 2012-03-04
      • 1970-01-01
      • 2013-06-01
      相关资源
      最近更新 更多