修罗武神 發表於 2023-12-27 10:53:24

使用正则表达式过滤 S3 上以 _$folder$ 结尾的占位文件的方法

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">Shell 实现</a></li><li><a href="#_label1">Java 实现</a></li><li><a href="#_label2">正则表达式文本过滤</a></li><ul class="second_class_ul"><li><a href="#_lab2_2_0">grep文本过滤</a></li><li><a href="#_lab2_2_1">正则表达式</a></li><li><a href="#_lab2_2_2">正则表达式和通配符的区别</a></li><li><a href="#_lab2_2_3">匹配字符串问题</a></li><li><a href="#_lab2_2_4">基本正则和扩展正则的区别</a></li></ul></ul></div><p>当我们使用命令行批量从 S3 上拷贝文件或统计文件数量时,希望能排除掉 S3 上以 <code>_$folder$</code> 结尾的占位文件,这个正则表达式应该怎么写呢?</p>
<p class="maodian"><a name="_label0"></a></p><h2>Shell 实现</h2>
<p>以下是统计 S3 某个位置下的除 <code>_$folder$</code> 结尾的文件的文件数量:</p>
<div class="jb51code"><pre class="brush:bash;">aws s3 ls --recursive s3://my-s3-location/ | grep -v '.*_\$folder\$' | wc -l</pre></div>
<p>使用 grep 过滤是比较简单的,因为 grep 有一个 <code>-v,--invert-match</code> 参数:&ldquo;反向匹配&rdquo;,即:过滤掉match 上的行。</p>
<p class="maodian"><a name="_label1"></a></p><h2>Java 实现</h2>
<p>相较而言,如果是 java 程序,这个正则就很有些难写了,应为 java 正则接口并没有&ldquo;反向匹配&rdquo;这种设置,这个 正则要这样写:<code>^(?!.*\$folder\$$).*$</code>,我们以 <code>s3-dist-cp</code> 这个命令为例,它的 <code>--srcPattern</code> 参数就是一个 Java 的正则表达式,用于匹配需要拷贝的文件,如果我们要在拷贝时排除掉 S3 上那些恼人的 <code>_$folder$</code> 结尾的文件,应该这样写:</p>
<div class="jb51code"><pre class="brush:bash;">nohup s3-dist-cp \
    -Dmapreduce.job.reduces=599 \
    --src=s3://my-hbase-snapshots/usertable-20231205 \
    --dest=hdfs://${SINK_CLUSTER_NAMENODES}:8020/user/hbase/ \
    --srcPattern='^(?!.*\$folder\$$).*$' \
    --multipartUploadChunkSize=1024 &amp;&gt; s3-dist-cp.out &amp;
tail -f s3-dist-cp.out</pre></div>
<p><span style="color:#ff0000"><strong>补充:</strong></span></p>
<p class="maodian"><a name="_label2"></a></p><h2>正则表达式文本过滤</h2>
<p class="maodian"><a name="_lab2_2_0"></a></p><h3>grep文本过滤</h3>
<p>1.grep 默认是按照以行为基本单位进行匹配和显示的。</p>
<p>2.grep默认匹配只要包含模式字符即可</p>
<p>grep -w 是按单词匹配,和普通的匹配不一致</p>
<p>单词的分隔符, 数字加字母加下划线都算做单词的一部分</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202312/2023122710524850.png" /></p>
<p>grep -f p.txt /etc/passwd</p>
<p>匹配显示结果的行号</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202312/2023122710524951.png" /></p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202312/2023122710524952.png" /></p>
<p>grep 并且关系和 或者关系</p>
<p>1.并且 grep root /etc/passwd | grep shutdown</p>
<p>2.或者 grep -e root -e shutdown /etc/passwd</p>
<p class="maodian"><a name="_lab2_2_1"></a></p><h3>正则表达式</h3>
<p>1.字符匹配</p>
<p>. 表示一个任意字符 .放在[]里面就表示.本身这个字符</p>
<p>2.匹配次数</p>
<p>某一个字符出现的次数</p>
<p>* 表示*号前面的字符出现的次数是不确定的</p>
<p>3.位置锚定</p>
<p>行首 ^ 不能匹配中间某段字符串的开始</p>
<p>行尾 $ 不能匹配中间某一段字符串的结尾</p>
<p>单词词首 \&lt;root root处于单词的最左侧</p>
<p>单词词尾 root\&gt; root处于单词的最右侧</p>
<p>4.分组</p>
<p>1. echo wangwangwangggww | grep &quot;\(wang\)\{3\}&quot;</p>
<p>2.后向引用</p>
<p class="maodian"><a name="_lab2_2_2"></a></p><h3>正则表达式和通配符的区别</h3>
<p>正则表达式匹配的是文件的内容或者标准输出的字符串,通配符匹配的是文件的名称.两者操作的对象不一致.</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202312/2023122710524953.png" /></p>
<p class="maodian"><a name="_lab2_2_3"></a></p><h3>匹配字符串问题</h3>
<p>shell执行命令的时候,正则表达式是以整个输出作为字符串内容,包括看不到的空格符号。</p>
<p>有些命令结果会输出一个或者多个空格,有些命令不会输出空格.</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202312/2023122710524954.png" /></p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202312/2023122710524955.png" /></p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202312/2023122710524956.png" /></p>
<p>1.在表达式中()符号前面和{}括号前面都必须要加上\(\) 和 \{\}.</p>
<p>grep &quot;^\(.*\):.*\1$&quot; /etc/passwd</p>
<p>2.正则表达式默认从字符串的最前面开始查找,但是如果锚定的是行尾,那么正则会从尾部开始查找</p>
<p>1.从尾部开始查找</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202312/2023122710524957.png" /></p>
<p>2.从头部开始查找</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202312/2023122710524958.png" /></p>
<p>3.分组实例</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202312/2023122710524959.png" /></p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202312/2023122710524960.png" /></p>
<p>第一分组匹配到的字符串是7,最后面的*\1 表示匹配到以7结尾而且7前面可以包含任意个数字的数字</p>
<p style="text-align:center"><img alt="" src="https://img.jbzj.com/file_images/article/202312/2023122710525061.png" /></p>
<p class="maodian"><a name="_lab2_2_4"></a></p><h3>基本正则和扩展正则的区别</h3>
<p>1.基本正则语法 小括号和大括号前面需要加上\符号做转义</p>
<p>grep -w &quot;\{2,3\}&quot; /etc/passwd</p>
<p>2.扩展正则 小括号和大括号前面不要加上转义字符</p>
<p>grep -Ew &quot;{2,3}&quot; /etc/passwd</p>
<p>egrep -w &quot;{2,3}&quot; /etc/passwd</p>
頁: [1]
查看完整版本: 使用正则表达式过滤 S3 上以 _$folder$ 结尾的占位文件的方法