提取每个文件的文件名、文件行数和文件大小

提取每个文件的文件名、文件行数和文件大小

想知道在文件夹中递归捕获一组文件的信息并将其记录为单独的管道分隔文件的最佳方法,如下所示

输出文件示例。

FOLDER_NM|FILE_NM|FILE_CNT|FILE_SIZE|DATE . 

SOME_FLD|xyz|35|350 MB| 10-05-2018  
SOME_FLD|abc|10|440 MB| 10-05-2018
SOME_FLD|pqr|85|800 MB| 10-05-2018 
SOME_FLD|lmn|40|200 MB| 10-05-2018 

答案1

您的linux标签表明statGNUsed在您的系统上可用;因此尝试

stat -c"%n|%s|%y" SOME_FLD/* | sed -r 'h; s/\|.*$//; s/^/wc -l </e; G; s/\n/|/; s/^([^|]*\|)([^|]*\|)/\2\1/; s/( [^ ]*){2}$//; s#/#|#' 
SOME_FLD|abc|235|2808|2018-10-05
SOME_FLD|lnm|235|2808|2018-10-05
SOME_FLD|pqr|235|2808|2018-10-05
SOME_FLD|xyz|235|2808|2018-10-05

stat列出必要的数据字段;sed,将行保存到保留缓冲区后,wc -l对文件名(GNU 扩展名)运行命令,然后将相关字段打乱到请求的顺序,然后进行一些修饰(从日期中删除时间字段,用/to替换|liles ' 路径)。

答案2

使用最新版本perl

find "$PWD" -type f -exec perl -MPOSIX -MNumber::Bytes::Human=format_bytes -e '
  while (<<>>) { if (eof) {
    my ($d, $f) = $ARGV =~ m{.*/(.*)/(.*)}s;
    my @s = stat ARGV;
    print join("|", $d, $f, $., format_bytes(tell ARGV),
               strftime("%Y-%m-%d", localtime $s[9])) . "\n";
    close ARGV;
  }}' {} +

(请注意,它会跳过空文件,并且(与 相反wc -l)将最后一个换行符之后的字符计为一行)。

或者与zsh

#! /bin/zsh -
zmodload zsh/stat
human() {
  local suffix
  REPLY=$1
  for suffix ('' K M G T P E) {
    ((REPLY<1024)) && break
    ((REPLY /= 1024.))
  }
  printf -v REPLY '%.1f%s' $REPLY $suffix
}
for file ($PWD/**/*(D-.)) {
  zstat -F %F -H info -- $file &&
    lines=$(($(wc -l < $file))) &&
    printf '%s\n' "$file:h:t|$file:t|$lines|$info[size]|$info[mtime]"
}

但这意味着wc -l每个文件运行一个,这将是相当低效的。

相关内容