Linux 标识单个unix目录中文本文件中的模式
如果我想在一个目录中识别Unix中的模式,我可以知道哪个Unix实用程序会有帮助吗(比如awk) 输入: $ls a_20171007_001.txtLinux 标识单个unix目录中文本文件中的模式,linux,shell,unix,awk,sed,Linux,Shell,Unix,Awk,Sed,如果我想在一个目录中识别Unix中的模式,我可以知道哪个Unix实用程序会有帮助吗(比如awk) 输入: $ls a_20171007_001.txt a_20171007_002.txt b_20171007_001.txt c_20180101_001.txt 预期输出: a_20171007_002.txt b_20171007_001.txt 无论文件创建时间如何,输出都应基于文件名返回文件的最新版本 输出文件不应具有未来日期的文件(例如,当前日期:20171008,因此20180101
a_20171007_002.txt
b_20171007_001.txt
c_20180101_001.txt 预期输出: a_20171007_002.txt
b_20171007_001.txt
非常感谢您的所有解决方案。但不幸的是,如果文件名不遵循任何模式,则没有帮助 例如,输入: ab_bc_全部\u 20171008\u 001.txt bc_cd_ad_全部\u 20171008\u 001.txt ab_bc_全部\u 20171008\u 002.txt ad_dc_cd_ed_全部\u 20180101\u 001.txt ae_bc_zx_ed_ac_全部\u 20170918_001.txt 输出: bc_cd_ad_all_20171008_001.txt ab_bc_all_20171008_002.txt ae_bc_zx_ed_ac_all_20170918_001.txt 在上述情况下,仅在'all'之后显示日期字段。 在上述情况下,你能提出建议吗
提前谢谢。请尝试以下内容,并让我知道这是否对您有帮助
ls -ltr *.txt | awk -v date=$(date +%Y) -F"_" 'prev != $1 && val && date_val<=date{print val} {prev=$1;val=$0;date_val=substr($2,1,4)} END{if(date_val<=date){print val}}'
ls-ltr*.txt | awk-v date=$(date+%Y)-F“|”prev!=$1&&val&&date\u val类似于Perl中的内容:
#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };
use Time::Piece;
my $today = localtime->ymd("");
my %latest;
for my $file (glob '*.txt') {
my ($id, $date, $num) = split /[_.]/, $file;
$latest{$id}{$date} = $num
if $date <= $today
&& (! exists $latest{$id}
|| ! exists $latest{$id}{$date}
|| $num > $latest{$id}{$date});
}
for my $id (keys %latest) {
for my $date (keys %{ $latest{$id} }) {
say "$id\_$date\_$latest{$id}{$date}.txt";
}
}
#/usr/bin/perl
使用警告;
严格使用;
使用特征qw{say};
使用时间::件;
my$today=localtime->ymd(“”);
我的最新百分比;
对于我的$file(glob'*.txt'){
我的($id,$date,$num)=拆分/[\.]/,$file;
$latest{$id}{$date}=$num
如果$date$latest{$id}{$date});
}
对于我的$id(密钥%latest){
对于我的$date(键%{$latest{$id}}){
说“$id\\$date\\$latest{$id}{$date}.txt”;
}
}
GNUAwk静态文件名格式的解决方案\uuuuuu.txt
:
示例性ls-1
输出(扩展):
一个简单的awk解决方案
$ awk -F_ -vdate=`date +%Y%m%d` ' !($1 in file) && $2<=date {file[$1]=$0} ($1 in file){if($0>=file[$1]){file[$1]=$0}} END{ for(i in file)print file[i] }' f1
a_20171007_002.txt
b_20171007_001.txt
$awk-F_-vdate=`date+%Y%m%d`!($1在文件中)和&$2=文件[$1]){文件[$1]=$0}}END{for(i在文件中)打印文件[i]}'f1
a_20171007_002.txt
b_20171007_001.txt
说明:
以yyyymmdd
在迭代记录/文件名时,如果文件名中的日期,即$2
小于或等于当前日期
,并且前缀(例如a、b等)在数组文件中不存在,则将其存储在文件数组中,例如文件['a']=a_20171007_001.txt
否则它不会被存储,在本例中,c_20180101_001.txt
将被直接拒绝
对于下一条记录,如果数组文件中存在前缀
,即$1
,则检查整个记录是否大于现有记录(按字典顺序)。如果是,覆盖文件数组中的记录。$ls-1r|awk-v today=“$(日期+%Y%m%d)”-F''.'($2此记录仅在shell(破折号)中可用
$ ls -1r | awk -v today="$(date +%Y%m%d)" -F'_' '($2 <= today) && !seen[$1,$2]++'
b_20171007_001.txt
a_20171007_002.txt
规格变更???
试试这个
d=$(date +%Y%m%d)
ls -1r *_*_*.txt|while read l
do
b="${l%_*_*}"
a="${l#$b*_}"
c="${a%_*}"
[ "$c" -le "$d" ] && [ "$v" != "$b$c" ] && { echo "$l";v="$b$c";}
done
您的版本号中可以有4位数字吗?如果是,它们是否只在999之后开始?例如a_20171007_999.txt
和a_20171007_1000.txt
?您能解释一下为什么这可以解决问题,而不是仅仅发布一些代码吗?这将更有帮助,特别是对初学者,谢谢。不,它是完全清晰、明显和简短的因此,任何不了解它的人都会从浏览手册页中受益匪浅。我想你要求对这个简短、琐碎的答案进行解释,但不是对这个页面上更长、更复杂的答案进行解释,因为有一个工具将它标记为可能的低质量,因为它非常简短。如果你不了解这个领域,那么就不要评论,只要move on.Compact代码很好而且很有帮助。但是解释是必要的,您也可以链接或引用一些手册页。或者对命令的作用进行非常简短的解释。这是您的决定,但这将提高答案的质量,当然也可以防止低质量的标志。
b_20171007_004.txt
a_20171007_0010.txt
$ awk -F_ -vdate=`date +%Y%m%d` ' !($1 in file) && $2<=date {file[$1]=$0} ($1 in file){if($0>=file[$1]){file[$1]=$0}} END{ for(i in file)print file[i] }' f1
a_20171007_002.txt
b_20171007_001.txt
$ ls -1r | awk -v today="$(date +%Y%m%d)" -F'_' '($2 <= today) && !seen[$1,$2]++'
b_20171007_001.txt
a_20171007_002.txt
d=$(date +%Y%m%d)
ls -1r *_*_*.txt|while IFS='_' read w x y
do
[ "$x" -le "$d" ] && [ "$v" != "$w$x" ] && { echo "$w"_"$x"_"$y";v="$w$x";}
done
d=$(date +%Y%m%d)
ls -1r *_*_*.txt|while read l
do
b="${l%_*_*}"
a="${l#$b*_}"
c="${a%_*}"
[ "$c" -le "$d" ] && [ "$v" != "$b$c" ] && { echo "$l";v="$b$c";}
done