正则表达式和Shell脚本

时间:2015-09-16 13:28:27

标签: regex shell

我学习了正则表达式和shell脚本。我有一个目录/ work / test /我有多个文件,如下列文件:needstc_30554-r-00051,profilemd5_30323-r-00053,unchanged_30394-r-00053。

我想从未更改的文件中提取第一个数字,例如/ changed_30397-r-30554文件,这个数字是30397。

我一直在使用正则表达式,并且能够使用以下内容从单个文件中提取id:

    str='profiles_060315091024_30398-r-00006.avro'
    myvar=$(awk -F'[_-]' '{print $3}' <<< "$str")

所以我的问题是:

我怎样才能进入该目录并仅从未更改的文件中获取第一个数字?

谢谢

4 个答案:

答案 0 :(得分:2)

我会使用 ls 的输出中的 Grep AWK (通过管道传输)。

ls | grep '^unchanged_' | awk -F'[_-]' '{print $2}'
  1. ls :获取目录的文件名
  2. grep :仅获取匹配的文件(文件名归档)
  3. awk :基本上这与原始样本相同(注意:数字应为$2

答案 1 :(得分:1)

步骤1)使用通配符选择匹配的文件:cd /work/test/ for file in unchanged_*; do number=${file#unchanged_} # remove "unchanged_" number=${number%%-*} # remove everything after dash echo "$number" done

步骤2)提取数字。您可以使用正则表达式,但使用纯shell结构更简单的方法是删除数字前后的内容。

这是什么样的:

Add()

答案 2 :(得分:1)

您可以使用find命令获取文件名列表,然后使用cut命令获取所需的部件。然后可以使用for循环迭代它们,但这需要所有结果都适合单个shell命令行,如果在目录中获得太多文件,则命令失败。 while循环将处理任意数量的文件。

find /work/test -type f -name 'unchanged*' | \
    cut -d_ -f2 | cut -d- -f1 | \
    while read fname;do echo $fname;done

如果您需要的只是值列表,则可以省略while循环 - 它就像占位符一样,以防您想对每个值执行某些操作。

find命令后的第一个参数是顶级目录; find将递归到任何子目录中。 “-type f”将其输出限制为常规文件。 -name选项将其输出限制为仅以未更改开头的文件。

“cut”是一个很好的实用工具,用于在分隔符之间拉出字段。第一个剪辑的“-d_”表示使用下划线作为分隔符,“-f2”表示抓住第二个字段;这给了我们下划线之后的一切。接下来,我们将破折号指定为分隔符并抓住第一个破折号之前的内容;这是我们的号码。我们得到了这些的流,每行一个,我们传入while循环。 read命令会一次将一个以空格分隔的单词读入给定的变量名称,让你随心所欲地使用它。

上述命令不能很好地处理包含换行符的异常文件名,或者包含空格的提取术语,但听起来并不像你在这里要处理的那样。

答案 3 :(得分:0)

我建议perl

#!/usr/bin/env perl

use strict;
use warnings;

#iterate files in current directory matching file spec
for ( glob("./unchanged_*") ) {
    #regular expression match first instance of 'one or more digits' into
    # $number
    if ( my ($number) = m/(\d+)/ ) {
        #print if that regex matched
        print $number, "\n";
    }
}

如果你愿意的话,你可以这样做。