Answers:
该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
ls
,printf "%s\n" b2* | head -1
将为您完成。
b2.10_5_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
find . -name "my-pattern" ... -print0
给我find: paths must precede expression: `...'
...
代表“更多参数”。如果您不需要它,请忽略它。
-r
到xargs命令行,该命令告诉xargs如果在标准输入中未收到任何内容,则不要运行其命令行。
-r
了答案。
这是必需的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 ]] \
&& 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\n' "$newest_file"
return 0
}
它仅使用Bash内置函数,并且应处理名称包含换行符或其他不寻常字符的文件。
nullglob_shopt=$(shopt -p nullglob)
,然后在以后$nullglob
放回nullglob
以前的样子。
$()
或反引号),因为它很慢,尤其是在Cygwin下,即使命令仅使用内置函数也是如此。同样,命令在其中运行的子外壳上下文有时可能导致它们以意外的方式运行。我还尝试避免将命令存储在变量中(例如nullglob_shopt
),因为如果错误地获取变量的值,可能会发生非常糟糕的事情。
cat
!”。即使需要花费更多的工作,它也可以显示人的概念。+1!
异常的文件名(例如包含有效\n
字符的文件可能会对这种解析造成破坏。这是在Perl中执行此操作的一种方法:
perl -le '@sorted = map {$_->[0]}
sort {$a->[1] <=> $b->[1]}
map {[$_, -M $_]}
@ARGV;
print $sorted[0]
' b2*
那是在那里使用的施瓦茨变换。
您可以使用stat
文件glob和decorate-sort-undecorate,并将文件时间添加在前面:
$ stat -f "%m%t%N" b2* | sort -rn | head -1 | cut -f2-
stat
,如果我没有记错的话。要在其他平台上获得类似的输出,可以使用stat -c $'%Y\t%n' b2* | sort -rn | head -n1 | cut -f2-
暗魔术函数咒语,适合那些想要上述find ... xargs ... head ...
解决方案的人,但是它们以易于使用的函数形式出现,因此您不必思考:
#define the function
find_newest_file_matching_pattern_under_directory(){
echo $(find $1 -name $2 -print0 | xargs -0 ls -1 -t | head -1)
}
#setup:
#mkdir /tmp/files_to_move
#cd /tmp/files_to_move
#touch file1.txt
#touch file2.txt
#invoke the function:
newest_file=$( find_newest_file_matching_pattern_under_directory /tmp/files_to_move/ bc* )
echo $newest_file
印刷品:
file2.txt
这是:
与给定格式匹配的给定目录下具有最旧文件修改时间戳的文件名。
使用find命令。
假设您使用的是Bash 4.2+,请使用-printf '%T+ %p\n'
文件时间戳值。
find $DIR -type f -printf '%T+ %p\n' | sort -r | head -n 1 | cut -d' ' -f2
例:
find ~/Downloads -type f -printf '%T+ %p\n' | sort -r | head -n 1 | cut -d' ' -f2
有关更有用的脚本,请参见此处的最新脚本:https : //github.com/l3x/helpers
有一种更有效的方法可以实现这一目标。考虑以下命令:
find . -cmin 1 -name "b2*"
该命令将查找一分钟前产生的最新文件,并在“ b2 *”上进行通配符搜索。如果您需要最近两天的文件,那么最好使用以下命令:
find . -mtime 2 -name "b2*"
“。” 代表当前目录。希望这可以帮助。