2014-09-06 95 views

回答

2

符號"${fn}"將所有文件名添加到單個參數字符串中,並用空格分隔。只是這一次,假設你不必擔心帶空格的文件名,你需要:

mv -f -- ${fn} /old 

如果您有空格的文件名,開始解析,然後你有問題輸出ls命令。

但是,如果您不必擔心文件名中的空格?

然後,正如我所說,你有大問題,從解析ls的輸出問題開始。

$ echo > 'a b' 
$ echo > ' c d ' 
$ 

兩個漂亮的文件名,其中包含空格。他們造成快樂的地獄。我即將假設你在Linux上或類似的東西。您需要使用bash陣列,stat命令,printf,sort -z,sed -z。或者你應該簡單地用空格來限制文件名;它可能更容易。

names=(*) 

陣列names包含每個文件名作爲一個單獨的數組元素,前緣和後緣和嵌入的空格都正確處理。

names=(*) 
for file in "${names[@]}" 
do printf "%s\0" "$(stat -c '%Y' "$file") $file" 
done | 
sort -nzr | 
sed -nze '1,30s/^[0-9][0-9]* //p' | 
tr '\0' '\n' 

for環分別評估每個文件的修改時間,和結合了修改時間,空間,和文件名成一個字符串後跟一個空字節來標記串的結束。 sort命令以數字方式對'行'進行排序,假設由於-z選項導致行由空字節終止,並且最先放置最近的文件名。 sed命令僅打印前30個'行'(文件名); tr命令用空行替換空字節(但這樣做會丟失文件名邊界的標識)。

代碼工作甚至用含有換行符的文件名,但只能在系統中sedsort支持(非標準)-z選項處理空終止輸入「線」 - 這意味着使用GNU sedsort系統(即使在Mac OS X上找到的BSD sed也沒有,儘管Mac OS X sort是GNU sort並確實支持-z)。

呃!該shell是爲空間出現在文件名之間而不是文件名而設計的。


作爲一個comment注意到BroSlow,如果你假設,那麼代碼可以更簡單,更接近便攜「在文件名中沒有新行」 - 但它仍然是棘手:

ls -t | 
tail -30 | 
{ 
list=() 
while IFS='' read -r file 
do list+=("$file") 
done 
mv -f -- "${list[@]}" /old 
} 

的需要使用IFS='',以便保留文件名中的前導空格和尾隨空格(以及製表符)。

我注意到Korn shell不需要大括號,但Bash可以。

+0

但是,如果您不必擔心文件名中的空格? – Gabe 2014-09-06 03:37:26

+0

然後你有重大問題!讓我冥想吧;這是非常不愉快的,無論如何。你在Linux或其他類Unix平臺上嗎? – 2014-09-06 03:39:16

+0

可以假定沒有帶有換行符的文件並解析'ls'輸出。但爲了完整性+1。 – BroSlow 2014-09-06 08:35:10