【问题标题】:Rename files to unique names and move them into a single destination directory将文件重命名为唯一名称并将它们移动到单个目标目录中
【发布时间】:2017-06-23 18:29:17
【问题描述】:

我有 100 个具有相同文件名的目录 content.html 以及其他文件。

我正在尝试将所有这些 content.html 文件复制到 1 个目录下,但由于它们具有相同的名称,因此会相互覆盖

那么我如何重命名并将所有这些移动到 1 个目录下

例如:

./0BD3D9D2-F8B1-4472-95C2-13319650A45C:
card.png  content.html    note.xhtml  quickLook.png   snippet.txt

./0EA34DB4-CD56-42BE-91DA-F631E44FB6E0:
card.png  content.html    note.xhtml  quickLook.png   related     snippet.txt

./1A33F29E-3938-4C2F-BA99-6B98FD045742:
card.png  content.html    note.xhtml  quickLook.png   snippet.txt

我尝试过的命令:

  1. 将 content.html 重命名为内容

    找到 . -类型 f | grep 内容.html |读 f;做 mv $f ${f/.html/};完成

  2. 将数字附加到文件名“内容”以使其唯一

    找到 . -类型 f | grep 内容 |读 f;做我=1;回声 mv $f $f$i.html;我=我+1;完成

MacBook-Pro$ 查找 . -类型 f | grep 内容 |读 f;做我=1;回声 mv $f $f$i.html;我=我+1;完成

mv ./0BD3D9D2-F8B1-4472-95C2-13319650A45C/content ./0BD3D9D2-F8B1-4472-95C2-13319650A45C/content1.html

mv ./0EA34DB4-CD56-42BE-91DA-F631E44FB6E0/content ./0EA34DB4-CD56-42BE-91DA-F631E44FB6E0/content1.html
mv ./1A33F29E-3938-4C2F-BA99-6B98FD045742/content ./1A33F29E-3938-4C2F-BA99-6B98FD045742/content1.html
  1. 一旦上述步骤成功,我应该能够这样做以实现我想要的输出:

    找到 . -类型 f | grep 内容 |读 f;做 mv $f ../;完成

但是,我确信我可以在 1 步命令中执行此操作,而且我的第 2 步也不起作用(递增 i)

知道为什么 step2 不起作用吗?

【问题讨论】:

    标签: bash


    【解决方案1】:

    bash 脚本:

    #!/bin/bash    
    find . -type f -name content.html | while IFS= read -r f; do
        name=$(basename $f)
        ((++i))
        mv "$f" "for_content/${name%.*}$i.html"
    done
    

    用您的目的地文件夹名称替换for_content

    【讨论】:

    • 感谢这工作!只需要找到。 -type (.) 缺失
    【解决方案2】:

    假设在您的基本目录中,您创建了一个名为 final 的文件夹用于存储 content.html 文件,然后执行以下操作

    find . -path ./final -prune -o -name "content.html" -print0 |
    while read -r -d '' name
    do 
    mv "$name" "./final/content$(mktemp -u XXXX).html"
    # mktemp with -u option just creates random characters, or it is just a dry run
    done
    

    最后,您将获得./final 文件夹下的所有 content.html 文件,格式为contentXXXX.html,其中XXXX 是随机字符。


    注意:find 中的-path ./final -prune -o 会阻止它下降到我们的结果文件夹。

    【讨论】:

      【解决方案3】:

      文件的 inode 应该是唯一的,因此您可以使用以下内容:

      find $(pwd) -name "content.html" -printf %f" "%i" "%p"\n" | awk '{ system("mv "$3" <directorytomoveto>"$2$1) }'  
      

      【讨论】:

      • 找到:-printf: 未知的主要或操作员
      • 我已经改为搜索 content.html
      • 我更早没有使用.py,所以错误仍然相同,可能是因为这不是linux - 这是mac(Darwin Kernel Version 16.1.0)?
      【解决方案4】:

      我会使用这样的东西:

      find . -type f -name 'test' | awk 'BEGIN{ cnt=0 }{ printf "mv %s ./output-dir/content_%03d.txt\n", $0, cnt++ }' | bash;
      

      您可以将 ./output-dir/ 替换为您的目标目录

      例子:

      [root@sl7-o2 test]# ls -R
      .:
      1  2  3  output-dir
      
      ./1:
      test
      
      ./2:
      test
      
      ./3:
      test
      
      ./output-dir:
      
      [root@sl7-o2 test]# find . -type f -name 'test' | awk 'BEGIN{ cnt=0 }{ printf "mv %s ./output-dir/content_%03d.txt\n", $0, cnt++ }' | bash;
      
      [root@sl7-o2 test]# ls ./output-dir/
      content_000.txt  content_001.txt  content_002.txt
      

      【讨论】:

        【解决方案5】:

        您可以使用shopt -s globstar 递归地抓取所有content.html 文件,然后使用循环重命名它们:

        #!/bin/bash
        
        set -o globstar
        counter=0
        dest_dir=/path/to/destination
        for f in **/content.html; do  # pick up all content.html files
          [[ -f "$f" ]] || continue   # skip if not a regular file
          mv "$f" "$dest_dir/content_$((++counter).html"
        done
        

        【讨论】:

          猜你喜欢
          • 2014-12-19
          • 1970-01-01
          • 2023-03-26
          • 2016-07-15
          • 2018-10-25
          • 2016-05-07
          • 2012-02-26
          • 1970-01-01
          • 2012-12-27
          相关资源
          最近更新 更多