2011-12-22 112 views
1

我有一个正常的...排序循环壳牌

for file in * 
do 
    #do something here 
done 

...代码。 问题是我想按自定义日期排序文件的行,日期是在文件的第二行中定义的。 我到这里的问题:

1.How才能知道什么是在这些多个文件的第二行我实际运行

for file in * do 

之前2.How我这个自定义字符串排序环路然后?

这并不工作,但也许它会帮助你理解我的问题:

for file in * 
do 
    customdate="$(sed -n 2p $file)" 
done 

for file in * sort by $customdate 
do 
    #do something here 
done 

回答

0

我认为你需要两个循环。第一个列表从文件中读取该日期并建立一个索引。第二个循环遍历该索引。您可以使用分隔符再次将索引拆分为再次从索引中获取文件名。

index="" 
for file in * 
do 
    customdate="$(head -2 $file | tail -1)" 
    index="${index}${customdate},${file}\n" 
done 

for key in `echo -e ${index} | sort` 
do 
    customdate=${key/,.*/} 
    file=${key/.*,/} 
    # PROCESS FILE HERE 
done 
+0

至少它排序的文件,但顺序仍然是错误的,因为我的日期看起来像12-22-11,这就是为什么这不起作用,但即使customdate看起来像22-12-11它仍然不起作用,因为具有customdate 01-01-12的文件肯定会更新,那么使用customdate 22-12-11的文件将会处于顶端:/ – 2011-12-22 15:37:11

+0

这就是为什么在文本文件中排序的首选日期格式是YYYYMMDD.HHMMSS。否则,您可以使用基于零的偏移量来分类来执行诸如(其中22-12-11在第一列中)'sort +0.6 -0.7 +0.3 -0.4 +0.0 -0.1'的事情。祝你好运! – shellter 2011-12-22 15:58:23

+0

好的。那么它可以工作thx – 2011-12-22 16:00:26

0

你应该只是做了两个循环起来,这样的事情:

for file in * 
do 
    customdate = "$(head -2 $file | tail -1)" 
    # do something here, e.g. pipe to sorting command, call sorting function, or whatever 
done 

这读取自定义像你一样从文件中获得日期(只是使用稍微不同的命令,主要是因为我在sed中吮吸)。目的是您可以在$file包含专有名称的同时获得$customdate,因此您可以在排序中同时使用这两个名称。

+0

是的,我可以但文件将按“最后修改日期”排序,然后而不是$ customdate权利? – 2011-12-22 13:56:19

+0

@Michael Perr:不,从文件读取'customdate',看到我在代码后面添加的文本。 – unwind 2011-12-22 13:58:26

+0

“...所以你可以在排序中使用它们。”怎么样,怎么样? – 2011-12-22 14:21:07

0

由于zsh的4.3.9dev2,有自定义排序一glob qualifier

oeo+是特殊情况;它们之后都是shell代码,分别与e glob限定符和+ glob限定符(参见上文)分隔。代码针对每个匹配文件执行,参数REPLY设置为条目上的文件名,globsort附加到zsh_eval_context。代码应以某种方式修改参数REPLY。返回时,使用参数的值而不是文件名作为要排序的字符串。

您可以使用此限定符来构建文件名列表。下面是由排序行的全部内容基本版本:

for file in *(oe\''REPLY=$({ read -r REPLY && IFS= read -r REPLY; } <$REPLY)'\'); do … 

如果您的日期仅由线的一部分,或者是在一些古怪的格式,围绕解析它。举例来说,如果你有一个欧洲风格的日期(日/月/年):

for file in *(oe\''REPLY=$({ read -r REPLY && IFS=/ read -r d m y && 
          REPLY=$((y*10000+m*100+d)); } <$REPLY)'\'); do … 

在任何外壳,就可以构建日期名字前缀列表,排序该列表,然后切出日期。我将假设没有任何文件名包含换行符,并且没有任何日期包含任何|字符。

names= 
IFS=' 
' 
for file in *; do 
    { read -r line; read -r line; } <"$file" 
    # If needed, process $line into something that is to be sorted lexicographically. 
    names="$names 
    $line|$file" 
done 
names=$(echo "$names" | sort) 
set -f 
for file in $names; do 
    set +f 
    file=${file#*|} 
    … 
done