2011-12-22 113 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