我学习了正则表达式和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")
所以我的问题是:
我怎样才能进入该目录并仅从未更改的文件中获取第一个数字?
谢谢
答案 0 :(得分:2)
我会使用 ls 的输出中的 Grep 和 AWK (通过管道传输)。
ls | grep '^unchanged_' | awk -F'[_-]' '{print $2}'
$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";
}
}
如果你愿意的话,你可以这样做。