<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Soul Of Free Loop &#187; 拷贝</title>
	<atom:link href="https://zohead.com/archives/tag/copy/feed/" rel="self" type="application/rss+xml" />
	<link>https://zohead.com</link>
	<description>Uranus Zhou&#039;s Blog</description>
	<lastBuildDate>Sat, 19 Jul 2025 15:42:46 +0000</lastBuildDate>
	<language>zh-CN</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.8</generator>
	<item>
		<title>Linux中拷贝目录跳过指定文件的方法</title>
		<link>https://zohead.com/archives/linux-copy-directory-ignore-files/</link>
		<comments>https://zohead.com/archives/linux-copy-directory-ignore-files/#comments</comments>
		<pubDate>Thu, 31 May 2012 16:30:44 +0000</pubDate>
		<dc:creator><![CDATA[Uranus Zhou]]></dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[Bash]]></category>
		<category><![CDATA[cp]]></category>
		<category><![CDATA[cpio]]></category>
		<category><![CDATA[find]]></category>
		<category><![CDATA[rsync]]></category>
		<category><![CDATA[Shell]]></category>
		<category><![CDATA[命令]]></category>
		<category><![CDATA[忽略]]></category>
		<category><![CDATA[拷贝]]></category>
		<category><![CDATA[目录]]></category>
		<category><![CDATA[跳过]]></category>

		<guid isPermaLink="false">http://zohead.com/?p=205</guid>
		<description><![CDATA[本文同步自（如浏览不正常请点击跳转）：https://zohead.com/archives/linux-copy-directory-ignore-files/ 近日在 Linux 环境中做版本迁移的时候遇到一个问题：需要将一个目录遍历拷贝到另一个目录中，但需要忽略其中的某些文件，由于目录中东西比较多，忽略的项也不好一一指定。普通的 cp 命令并没有排除某个文件或文件夹的参数，比较丑陋点可以 cp -r 拷贝完目录之后再去删除无用的，但如果做批量脚本操作就不爽了，经过实际试验之后暂时找到两个比较好的方法。 1、使用 rsync 进行拷贝： rsync 本来是文件同步备份的工具，相对于普通的  [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>本文同步自（如浏览不正常请点击跳转）：<a href="https://zohead.com/archives/linux-copy-directory-ignore-files/" target="_blank">https://zohead.com/archives/linux-copy-directory-ignore-files/</a></p>
<p>近日在 Linux 环境中做版本迁移的时候遇到一个问题：需要将一个目录遍历拷贝到另一个目录中，但需要忽略其中的某些文件，由于目录中东西比较多，忽略的项也不好一一指定。普通的 cp 命令并没有排除某个文件或文件夹的参数，比较丑陋点可以 cp -r 拷贝完目录之后再去删除无用的，但如果做批量脚本操作就不爽了，经过实际试验之后暂时找到两个比较好的方法。</p>
<p><strong>1、使用 rsync 进行拷贝：</strong></p>
<p>rsync 本来是文件同步备份的工具，相对于普通的 cp 命令，rsync 在控制方面就强多了，而且 rsync 对遍历目录也支持，有 --exclude 参数可以忽略指定的文件或文件夹。</p>
<p><em><span style="color: #008000;">rsync -vaP --exclude=".*" --exclude="Makefile" dir1 /home/dir2</span></em></p>
<p>如上面演示的就可以排除掉隐藏文件和 Makefile 文件，-a 参数已经包含遍历处理参数 -r。</p>
<p><strong>2、使用 find 加 cpio 进行拷贝：</strong></p>
<p>备注：此方法来自 Advanced Bash-Scripting Guide，需要了解的童鞋自己去参考了。</p>
<p>用过 find 的童鞋都知道，find 对文件的过滤那是非常强大的，配合 cpio 来进行目录的遍历拷贝就可以实现过滤指定的文件或文件夹，当然也可以做到只备份特定的文件或文件夹，你可以用 find 的各种过滤参数达到拷贝哪天的文件，拷贝近期更改的文件等特殊效果，而且 find 支持正则表达式，这种方式想比第一种使用 rsync 跳过文件的方式更加灵活，因此非常推荐使用此方式进行目录拷贝。</p>
<p><em><span style="color: #008000;">cd dir1<br />
find . -regextype posix-egrep -mindepth 1 ! -regex './(dev|tmp)($|/.*)' ! -name Makefile -a ! -name .svn | cpio -admvp /home/dir2<br />
</span></em></p>
<p>小解释下：</p>
<p>find 的 -regextype 参数指定正则表达式类型，posix-egrep 为 egrep 用的扩展正则表达式，-mindepth 使 find 的输出中不包括目录本身，-regex 参数指定过滤的文件的正则表达式，-regex 前面的感叹号表示跳过，'./(dev|tmp)($|/.*)' 这个正则表达式即表示跳过目录中的第一层 dev 和 tmp 目录以及下面所有的文件和文件夹，最后两个 -name 指定要跳过文件名为 Makefile 和 .svn 的文件，这样在备份版本库的时候非常有用。</p>
<p>cpio 命令将 find 的输出文件列表依次拷贝到 /home/dir2 目标目录中，-a 表示不更新文件的访问时间，-d 指定自动创建目录，-m 指定保留文件的修改时间，-p 指定 cpio 工作在 Copy-pass 模式，这是专门用来拷贝目录树的一种模式。</p>
<p>PS：如果有更加简单的方法，欢迎提出指正哦~~~ ^_^</p>
]]></content:encoded>
			<wfw:commentRss>https://zohead.com/archives/linux-copy-directory-ignore-files/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>vector的push_back拷贝构造和空间占用分析</title>
		<link>https://zohead.com/archives/vector-push-back-space-copy/</link>
		<comments>https://zohead.com/archives/vector-push-back-space-copy/#comments</comments>
		<pubDate>Fri, 04 May 2012 18:30:56 +0000</pubDate>
		<dc:creator><![CDATA[Uranus Zhou]]></dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[技术]]></category>
		<category><![CDATA[push_back]]></category>
		<category><![CDATA[STL]]></category>
		<category><![CDATA[拷贝]]></category>
		<category><![CDATA[构造]]></category>
		<category><![CDATA[析构]]></category>
		<category><![CDATA[编程]]></category>

		<guid isPermaLink="false">http://zohead.com/?p=104</guid>
		<description><![CDATA[本文同步自：https://zohead.com/archives/vector-push-back-space-copy/ 这两天在实际程序中使用 STL 的 vector push_back 类对象时出现问题，偶尔发现 vector 在 push_back 时的调用类对象的拷贝构造函数和析构函数有点特别，简单做下分析。 程序代码： 功能很简单，main 中定义一个 sss 类对象和对应的 vector，然后在循环中改类成员的值，并依次 push_back 到 vector 中，类的构造函数、析构函数、拷贝构造函数中都加了对应的打印输出。循环运行了5次，往 vector 中增加了5个类成员。 [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>本文同步自：<a href="https://zohead.com/archives/vector-push-back-space-copy/" target="_blank">https://zohead.com/archives/vector-push-back-space-copy/</a></p>
<p>这两天在实际程序中使用 STL 的 vector push_back 类对象时出现问题，偶尔发现 vector 在 push_back 时的调用类对象的拷贝构造函数和析构函数有点特别，简单做下分析。</p>
<p><span style="color: #f00;"><strong>程序代码：</strong></span></p>
<p><pre class="brush: cpp; highlight: [11,16,22,36]; title: cat &gt; test.cpp; notranslate">
#include &lt;iostream&gt;
#include &lt;vector&gt;

using namespace std;

struct sss
{
public:
	explicit sss(int val) : value(val)
	{
		cout &lt;&lt; &quot;---init sss &quot; &lt;&lt; this &lt;&lt; &quot;, value:&quot; &lt;&lt; value &lt;&lt; endl;
	}

	sss(const sss&amp; org)
	{
		cout &lt;&lt; &quot;---copy &quot; &lt;&lt; &amp;org &lt;&lt; &quot; to &quot; &lt;&lt; this &lt;&lt; endl;
		value = org.value;
	}

	~sss()
	{
		cout &lt;&lt; &quot;---destory sss &quot; &lt;&lt; this &lt;&lt; &quot;, value:&quot; &lt;&lt; value &lt;&lt; endl;
	}
 
	int value;
};

int main(int argc, char ** argv)
{
	sss s_tmp(11);
	int i = 0;
	vector&lt;sss&gt; vvv;

	for (i = 0; i &lt; 5; i++) {
		s_tmp.value++;
		vvv.push_back(s_tmp);
		cout &lt;&lt; &quot;size: &quot; &lt;&lt; vvv.size() &lt;&lt; &quot;, capacity: &quot; &lt;&lt; vvv.capacity() &lt;&lt; endl;
	}

	return 0;
}
</pre>
</p>
<p>功能很简单，main 中定义一个 sss 类对象和对应的 vector，然后在循环中改类成员的值，并依次 push_back 到 vector 中，类的构造函数、析构函数、拷贝构造函数中都加了对应的打印输出。循环运行了5次，往 vector 中增加了5个类成员。</p>
<p>实际运行输出如下：</p>
<hr size="1" />
<p>---init sss 0x22ff20, value:11<br /> ---copy 0x22ff20 to 0x5d2a58<br /> size: 1, capacity: 1<br /> ---copy 0x5d2a58 to 0x5d2ad8<br /> ---copy 0x22ff20 to 0x5d2adc<br /> ---destory sss 0x5d2a58, value:12<br /> size: 2, capacity: 2<br /> ---copy 0x5d2ad8 to 0x5d2ae8<br /> ---copy 0x5d2adc to 0x5d2aec<br /> ---copy 0x22ff20 to 0x5d2af0<br /> ---destory sss 0x5d2ad8, value:12<br /> ---destory sss 0x5d2adc, value:13<br /> size: 3, capacity: 4<br /> ---copy 0x22ff20 to 0x5d2af4<br /> size: 4, capacity: 4<br /> ---copy 0x5d2ae8 to 0x5d2b00<br /> ---copy 0x5d2aec to 0x5d2b04<br /> ---copy 0x5d2af0 to 0x5d2b08<br /> ---copy 0x5d2af4 to 0x5d2b0c<br /> ---copy 0x22ff20 to 0x5d2b10<br /> ---destory sss 0x5d2ae8, value:12<br /> ---destory sss 0x5d2aec, value:13<br /> ---destory sss 0x5d2af0, value:14<br /> ---destory sss 0x5d2af4, value:15<br /> size: 5, capacity: 8<br /> ---destory sss 0x5d2b00, value:12<br /> ---destory sss 0x5d2b04, value:13<br /> ---destory sss 0x5d2b08, value:14<br /> ---destory sss 0x5d2b0c, value:15<br /> ---destory sss 0x5d2b10, value:16<br /> ---destory sss 0x22ff20, value:16</p>
<hr size="1" />
<p><span style="color: #f00;"><strong>结果分析：<br /> </strong></span></p>
<p>vector 每次调用 push_back 时都会拷贝一个新的参数指定的 sss 类对象，这会调用 sss 的拷贝构造函数，第一次的 copy 正常，而且 vector 的实际容量也由 0  变为 1。</p>
<p>第二次调用 push_back，通过输出会发现调用了两次拷贝构造函数，一次析构函数，原来 vector 此时判断容量不够，将容量扩大为原来的两倍，变为 2，并将原来的元素再次拷贝一份存放到新的内存空间，然后拷贝新加的类对象，最后再释放原来的元素。</p>
<p>第三次调用 push_back 时，vector 自动扩大为4，因此拷贝构造函数调用了3次，析构函数调用了2次，程序最终退出了时就析构了 5 次加本身的 sss 类对象一共 6 次。</p>
<p><span style="color: #f00;"><strong>参考：</strong></span></p>
<p>由此看来，vector 的 push_back 在发现空间不足时自动将空间以 2 的指数增长：0 -&gt; 1 -&gt; 2 -&gt; 4 -&gt; 8 -&gt; 16 -&gt; 32 ...</p>
<p>查找资料后得知，如此设计的主要目的是为了尽可能的减小时间复杂度；如果每次都按实际的大小来增加 vector 的空间，会造成时间复杂度很高，降低 push_back 的速度。</p>
<p>另外关于 push_back 为什么会执行拷贝构造函数，push_back 的原型为：</p>
<p><em><span style="color: #008000;">void push_back(const _Ty&amp; _Val)</span></em></p>
<p>参数是以引用方式传递，按说不会拷贝，但 push_back 实际实现中判断空间不足时是调用 insert 函数添加元素：</p>
<p><em><span style="color: #008000;">void push_back(const _Ty&amp; _Val)</span></em><br /> <em><span style="color: #008000;">{</span></em><br /> <em><span style="color: #008000;">   // insert element at end</span></em><br /> <em><span style="color: #008000;">   if (size() &lt; capacity())</span></em><br /> <em><span style="color: #008000;">   #if _HAS_ITERATOR_DEBUGGING</span></em><br /> <em><span style="color: #008000;">   {</span></em><br /> <em><span style="color: #008000;">      // room at end, construct it there</span></em><br /> <em><span style="color: #008000;">      _Orphan_range(_Mylast, _Mylast);</span></em><br /> <em><span style="color: #008000;">      _Mylast = _Ufill(_Mylast, 1, _Val);</span></em><br /> <em><span style="color: #008000;">   }</span></em><br /> <em><span style="color: #008000;">   #else /* _HAS_ITERATOR_DEBUGGING */</span></em><br /> <em><span style="color: #008000;">      _Mylast = _Ufill(_Mylast, 1, _Val);</span></em><br /> <em><span style="color: #008000;">   #endif /* _HAS_ITERATOR_DEBUGGING */</span></em><br /> <em><span style="color: #008000;">   else</span></em><br /> <em><span style="color: #008000;">      insert(end(), _Val);</span></em><br /> <em><span style="color: #008000;">}</span></em></p>
<p><span style="color: #f00;"><strong>更新：</strong></span></p>
<p>2012-05-10：</p>
<p>近期在 Visual Studio 2010 中发现 vector 的实际空间增加顺序为：1 - 2 - 3 - 4 - 6 - 9 - 13 - 19 - 28 - 42 - 63 - 94 - 141 - 211 ...，有空时再继续研究。</p>
<p>以上只是个人粗略分析，有任何问题欢迎指正，玩的开心咯 ^_^</p>
]]></content:encoded>
			<wfw:commentRss>https://zohead.com/archives/vector-push-back-space-copy/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
