如何复制已选择文件的文件夹和子文件夹

时间:2019-09-26 12:25:00

标签: linux bash

我有一个目录oridir,其结构如下:

.
├── DIRA
│   ├── DIRA1
│   │   └── file2.txt
│   └── DIRA2
│       ├── file1.xls
│       └── file1.txt
└── DIRB
    ├── DIRB1
    │   └── file1.txt
    └── DIRB2
        └── file2.xls

我必须在保持目录结构的同时复制扩展名为.xls的文件。因此,我需要在newdir文件夹中包含以下目录和文件:

.
├── DIRA
│   └── DIRA2
│       └── file1.xls
└── DIRB
    └── DIRB2
        └── file2.xls

我尝试了以下命令,但它会复制所有文件和文件夹:

cp -r oridir newdir

可以按以下步骤查找所需文件:

$ find oridir | grep xls$
oridir/DIRB/DIRB2/file2.xls
oridir/DIRA/DIRA2/file1.xls

也如下:

$ find oridir -type f -iname *.xls
./oridir/DIRB/DIRB2/file2.xls
./oridir/DIRA/DIRA2/file1.xls

但是如何创建这些文件夹和复制文件。如何在Linux中使用“ bash”实现选定的目录创建和复制文件?

编辑:某些文件和目录名称中也有空格。

3 个答案:

答案 0 :(得分:1)

cp的--parents标志在DIRECTORY下使用完整的源文件名

例如,如果启用了递归全局**shopt -s globstar):

cp --parents origin/**/*.xls target

如果未启用递归glob,则必须为目录层次结构上的每个级别添加通配符:

cp --parents origin/*/*/*.xls target

答案 1 :(得分:1)

如果目标目录为“目的地”。

foo.sh

   var linkedResources = new List<LinkedResource>();
   try
   {
       HtmlDocument bodyDoc = new HtmlDocument();
       bodyDoc.OptionDefaultStreamEncoding = Encoding.UTF8;
       bodyDoc.LoadHtml(Body);
       var nodes = bodyDoc.DocumentNode.SelectNodes("//img[@src]");

       if (nodes != null && nodes.Count > 0)
       {
           foreach (HtmlNode link in nodes)
           {

               HtmlAttribute att = link.Attributes["src"];
               int id;
               if (att.Value.IndexOf("image/get?id=") > -1 && int.TryParse(att.Value.Substring(att.Value.IndexOf("image/get?id=") + "image/get?id=".Length), out id))
               {
                   if (id == 0)
                   {
                       HtmlAttribute altAttr = link.Attributes["alt"];
                       if (altAttr.Value.IndexOf("image/get?id=") > -1 &&
                           int.TryParse(
                               altAttr.Value.Substring(altAttr.Value.IndexOf("image/get?id=") + "image/get?id=".Length),
                               out id))
                       {
                       }
                   }
                   try
                   {
                    var image = ImageRepository.Get(id);
                    if (image != null)
                    {

                        var inlineImage = new LinkedResource(new MemoryStream(image.Data), image.ContentType)
                        {
                            ContentId = Guid.NewGuid().ToString()
                        };


                        att.Value = string.Format("cid:{0}", inlineImage.ContentId);
                        linkedResources.Add(inlineImage);
                    }

                }
                   catch (Exception e)
                   {
                        log.Info(e.Message);
                   }
               }
           }

        var view = AlternateViews.FirstOrDefault();

        log.Info("Embedded Images LOG");

        if (view == null)
        {
            log.Info("Embedded Images Info: View IS NULL");
            view = AlternateView.CreateAlternateViewFromString(Body, null, "text/html");
        }
        else
        {
            log.Info("Embedded Images Info: View IS NOT NULL");
        }

        foreach (var resource in linkedResources)
        {
            log.Info("Embedded Images Info: Adding Linked Resources");
            view.LinkedResources.Add(resource);
        }

        AlternateViews.Add(view);

        Stream stream = new MemoryStream();
           bodyDoc.Save(stream);
           stream.Seek(0, SeekOrigin.Begin);
           StreamReader sr = new StreamReader(stream);
           Body = sr.ReadToEnd();
    }

   }
   catch (Exception e)
   {
       log.Info(e.Message);
   }

制作目录和文件。

#!/bin/bash
dest=./dest
find . -type f -name "*.xls" | while read f
do
    d=$(dirname "${f}")                                                         
    d="${dest}/${d}"
    mkdir -p "${d}"
    cp "${f}" "${d}"
done

结果是

$ mkdir -p DIRA/DIRA1
$ mkdir -p DIRA/DIRA2
$ mkdir -p DIRB/DIRB1
$ mkdir -p DIRB/DIRB2
$ touch DIRA/DIRA1/file2.txt
$ touch DIRA/DIRA2/file1.xls
$ touch DIRA/DIRA2/file1.txt
$ touch DIRB/DIRB1/file1.txt
$ touch DIRB/DIRB1/file2.xls

答案 2 :(得分:1)

请先查看Yuji的出色答案,但我认为tar在这里也是不错的选择:

cd oridir; find . -name "*.xls" | xargs tar c | (cd ../newdir; tar x)

您可能需要根据目录的精确路径来调整oridir和/或../newdir

可能的改进:这是一个更好的版本,它将处理名称中带有空格(或其他奇怪字符)的文件(和路径),并使用tar自己的选项代替xargscd

cd oridir; find . -print0 -name "*.xls" | tar -c --null -T- | tar -C ../newdir -x

说明:

-print0--null导致各自的命令仅使用空(ASCII 0)字符分隔文件名。

-T-使tar从标准输入中读取文件名。

-C导致tarcd提取。