我有一个目录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”实现选定的目录创建和复制文件?
编辑:某些文件和目录名称中也有空格。
答案 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
自己的选项代替xargs
和cd
:
cd oridir; find . -print0 -name "*.xls" | tar -c --null -T- | tar -C ../newdir -x
说明:
-print0
和--null
导致各自的命令仅使用空(ASCII 0)字符分隔文件名。
-T-
使tar
从标准输入中读取文件名。
-C
导致tar
到cd
提取。