Bash 函数查找与模式匹配的最新文件

2024-10-18 09:00:00
admin
原创
72
摘要:问题描述:在 Bash 中,我想创建一个函数,返回与特定模式匹配的最新文件的文件名。例如,我有一个文件目录,如下所示:Directory/ a1.1_5_1 a1.2_1_4 b2.1_0 b2.2_3_4 b2.3_2_0 我想要以“b2”开头的最新文件。如何在 bash 中执...

问题描述:

在 Bash 中,我想创建一个函数,返回与特定模式匹配的最新文件的文件名。例如,我有一个文件目录,如下所示:

Directory/
   a1.1_5_1
   a1.2_1_4
   b2.1_0
   b2.2_3_4
   b2.3_2_0

我想要以“b2”开头的最新文件。如何在 bash 中执行此操作?我需要将其包含在~/.bash_profile脚本中。


解决方案 1:

ls命令有一个按时间排序的参数-t。然后您可以使用 抓取第一个(最新的)head -1

ls -t b2* | head -1

但要注意:为什么不应该解析 ls 的输出

我的个人观点:ls当文件名包含空格或换行符等奇怪字符时,解析是危险的。

如果您可以保证文件名不包含奇怪的字符(可能是因为您可以控制文件的生成方式),那么解析ls是相当安全的。

如果您正在开发一个脚本,该脚本需要由许多人在许多不同情况下在许多系统上运行,那么请不要解析ls

安全操作方法如下:

unset -v latest
for file in "$dir"/*; do
  [[ $file -nt $latest ]] && latest=$file
done

有关更多解释,请阅读如何在目录中找到最新(最新、最早、最旧)的文件?

测试、单方括号和双方括号之间有什么区别?

解决方案 2:

find和的组合ls非常适合

  • 文件名不带换行符

  • 文件数量不是很多

  • 文件名不太长

解决方案:

find . -name "my-pattern" -print0 |
    xargs -r -0 ls -1 -t |
    head -1

让我们分解一下:

我们可以匹配所有有趣的文件,如下find所示:

find . -name "my-pattern" ...

然后使用-print0我们可以将所有文件名安全地传递给ls这样的:

find . -name "my-pattern" -print0 | xargs -r -0 ls -1 -t

find可以在此处添加其他搜索参数和模式

find . -name "my-pattern" ... -print0 | xargs -r -0 ls -1 -t

ls -t将按修改时间对文件进行排序(最新的在前),并一行打印一个。您可以使用-c按创建时间排序。注意:这将中断包含换行符的文件名。

最后head -1得到排序列表中的第一个文件。

注意: xargs使用系统限制参数列表的大小。如果超出此大小,xargs将多次调用ls。这将破坏排序,也可能破坏最终输出。运行

xargs  --show-limits

检查你的系统的限制。

注2:find . -maxdepth 1 -name "my-pattern" -print0如果您不想通过子文件夹搜索文件,请使用。

注 3:正如 @starfry 指出的那样 -如果没有文件与 匹配,-r的参数xargs将阻止 的调用。感谢您的建议。ls -1 -t`find`

解决方案 3:

这是所需 Bash 函数的可能实现:

# Print the newest file, if any, matching the given pattern
# Example usage:
#   newest_matching_file 'b2*'
# WARNING: Files whose names begin with a dot will not be checked
function newest_matching_file
{
    # Use ${1-} instead of $1 in case 'nounset' is set
    local -r glob_pattern=${1-}

    if (( $# != 1 )) ; then
        echo 'usage: newest_matching_file GLOB_PATTERN' >&2
        return 1
    fi

    # To avoid printing garbage if no files match the pattern, set
    # 'nullglob' if necessary
    local -i need_to_unset_nullglob=0
    if [[ ":$BASHOPTS:" != *:nullglob:* ]] ; then
        shopt -s nullglob
        need_to_unset_nullglob=1
    fi

    newest_file=
    for file in $glob_pattern ; do
        [[ -z $newest_file || $file -nt $newest_file ]] \n            && newest_file=$file
    done

    # To avoid unexpected behaviour elsewhere, unset nullglob if it was
    # set by this function
    (( need_to_unset_nullglob )) && shopt -u nullglob

    # Use printf instead of echo in case the file name begins with '-'
    [[ -n $newest_file ]] && printf '%s
' "$newest_file"

    return 0
}

它仅使用 Bash 内置命令,并且可以处理名称包含换行符或其他不寻常字符的文件。

解决方案 4:

使用查找命令。

假设您正在使用 GNU find,您可以将其`-printf '%T+ %p
'`用于文件时间戳值。

find . -type f -printf '%T+ %p
' | sort -r | head -n 1 | cut -d' ' -f2

例子:

find ~/Downloads -type f -printf '%T+ %p
' | sort -r | head -n 1 | cut -d' ' -f2

有关更有用的脚本,请参阅此处的find-latest脚本:https: //github.com/l3x/helpers

解决方案 5:

您可以使用stat文件 glob 和 decorate-sort-undecorate 并在前面添加文件时间:

$ stat -f "%m%t%N" b2* | sort -rn | head -1 | cut -f2-

正如评论所述,最好的跨平台解决方案可能是使用 Python、Perl 或 Ruby 脚本。

对于这样的事情,我倾向于使用 Ruby,因为它非常容易编写小型、一次性脚本,同时又具有从命令行执行的 Python 或 Perl 的强大功能。

这是一颗红宝石:

ruby -e '
# index [0] for oldest and [-1] for newest
newest=Dir.glob("*").
    reject { |f| File.directory?(f)}.
    sort_by { |f| File.birthtime(f) rescue File.mtime(f) 
    }[-1]
p newest'

这将获取当前工作目录中的最新文件。

**/*您还可以通过使用in使 glob 递归,或使用等glob限制匹配的文件b2*

解决方案 6:

Bash 函数用于查找与模式匹配的目录下的最新文件

#1.  Make a bash function:
newest_file_matching_pattern(){ 
    find $1 -name "$2" -print0 | xargs -0 ls -1 -t | head -1  
} 
 
#2. Setup a scratch testing directory: 
mkdir /tmp/files_to_move;
cd /tmp/files_to_move;
touch file1.txt;
touch file2.txt; 
touch foobar.txt; 
 
#3. invoke the function: 
result=$(newest_file_matching_pattern /tmp/files_to_move "file*") 
printf "result: $result
"

印刷:

result: /tmp/files_to_move/file2.txt

或者,如果脆弱的 bash parlor tricks 分包给 python 解释器更符合你的视角,那么这会做同样的事情:

#!/bin/bash 
 
function newest_file_matching_pattern { 
python - <<END 
import glob, os, re  
print(sorted(glob.glob("/tmp/files_to_move/file*"), key=os.path.getmtime)[0]); 
END 
} 
 
result=$(newest_file_matching_pattern) 
printf "result: $result
" 

印刷:

result: /tmp/files_to_move/file2.txt

解决方案 7:

不常见的文件名(比如包含有效`
`字符的文件)可能会对这种解析造成严重破坏。以下是在 Perl 中执行此操作的一种方法:

perl -le '@sorted = map {$_->[0]} 
                    sort {$a->[1] <=> $b->[1]} 
                    map {[$_, -M $_]} 
                    @ARGV;
          print $sorted[0]
' b2*

那里使用的就是Schwartzian 变换。

解决方案 8:

对于 Google 员工来说:

ls -t | head -1

  • -t按上次修改日期时间排序

  • head -1仅返回第一个结果

(请勿在生产中使用)

解决方案 9:

合并find、、和。stat​​sort`cut`tail

  1. find文件-type f(匹配名称-name 'b2*'

  2. xargs stat统计这些文件打印%Y自纪元以来的秒数和%n文件名

  3. sort

  4. cut字段-f2 及以上2-(制表符分隔)

  5. tail最后-n 1一个获取最新文件

适用于所有使用 GNU coreutils 的 shell

tab=$(printf '    ');
find . -type f -print0 |
  xargs -0 stat --format "%Y$tab%n" |
  sort |
  cut -f 2- |
  tail -n 1

可以随意用“$tab”替换文字制表符,但它在 SO 上不起作用。

OP 要求过滤以 开头的文件的名称b2,因此

tab=$(printf '    ');
find . -type f -name 'b2*' -print0 |
  xargs -0 stat --format "%Y$tab%n" |
  sort |
  cut -f 2- |
  tail -n 1

解决方案 10:

有一种更有效的方法可以实现这一点。考虑以下命令:

find . -cmin 1 -name "b2*"

此命令使用通配符搜索“b2*”查找一分钟前生成的最新文件。如果您想要过去两天的文件,那么最好使用以下命令:

find . -mtime 2 -name "b2*"

“.”代表当前目录。希望这能有所帮助。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用