首页 > 解决方案 > 模式匹配“hdfs ds -ls”输出时如何忽略时间戳?

问题描述

我有存储在 HDFS 上的文件,它们的名称后缀有一个日期,与文件的修改日期不同,如下所示:

$hdfs dfs -ls /a/b/c/d/e/*
Found 5 items
drwxr-xr-x - xuser xuser 0 2015-05-01 13:59 /a/b/c/d/e/exp_dt=2016-01-05
drwxr-xr-x - xuser xuser 0 2017-10-10 15:42 /a/b/c/d/e/exp_dt=2015-05-01

我正在尝试仅使用给定的exp_dt. 目前,努力如下:

inputDir=/a/b/c/d/e/                                                                                                       
countCmd='hdfs dfs -ls $inputDir | grep '\.2015$''
hduCmdOutput=`eval $countCmd`
echo $hduCmdOutput

...具有输出:

drwxr-xr-x - xuser xuser 0 2015-05-01 13:59 /a/b/c/d/e/exp_dt=2016-01-05 drwxr-xr-x - xuser xuser 0 2017-10-10 15:42 /a/b/c/d/e/exp_dt=2015-05-01

而我想要的是:

drwxr-xr-x - xuser xuser 0 2017-10-10 15:42 /a/b/c/d/e/exp_dt=2015-05-01

当我只想匹配文件名本身时,如何防止文件的日期戳(修改时间)匹配?

标签: shellhadoopsh

解决方案


匹配您的特定模式

如果您只想在exp_dt=或之后立即过滤年份day_id=,请将过滤器设置为仅在该位置匹配:

hdfs dfs -ls '/a/b/c/d/e/*' | grep -Ee '(exp_dt|day_id)=2015-'

或者,如果您只想2015-??-??在行尾匹配,则可能如下所示:

hdfs dfs -ls '/a/b/c/d/e/*' | grep -Ee '2015-..-..$'

注意这里没有eval。如果您想存储此代码以多次运行它(使用可能更改的参数),请使用以下函数:

filesForYear() {
  local path=$1 year=$2
  hdfs dfs -ls "$path/*" | grep -Ee "(exp_dt|day_id)=$year"
}

...然后可以称为:

filesForYear /a/b/c/d/e 2015

或者

filesForYear /e/f/g 2016

...ETC。


一般只搜索文件名

考虑以下函数:

grepHdfsList() {
  local path=$1 pattern=$2
  while read -r line; do
    read -r _ _ _ _ _ _ _ filename <<<"$line"
    [[ $filename =~ $pattern ]] && printf '%s\n' "$line"
  done < <(hdfs dfs -ls "$path")
}

对于从 读取的每一行hdfs dfs -ls,它仅提取文件名,仅将文件名与模式匹配,但如果该模式匹配则打印整行。(如果您只想打印文件名,您可以更改printf '%s\n' "$line"为)。printf '%s\n' "$filename"

调用可能如下所示:

grepHdfsList /a/b/c/d/e 2015

推荐阅读