#! /bin/sh -
cd /PHOTAN || exit
fn=$(ls -t | tail -n -30)
mv -f -- "${fn}" /old
所有我想要的待辦事項是保持最近30個文件...但不能讓過去的MV 「文件名過長」問題「文件名太長」的bash mv命令舊文件
請幫忙」
#! /bin/sh -
cd /PHOTAN || exit
fn=$(ls -t | tail -n -30)
mv -f -- "${fn}" /old
所有我想要的待辦事項是保持最近30個文件...但不能讓過去的MV 「文件名過長」問題「文件名太長」的bash mv命令舊文件
請幫忙」
符號"${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
命令用空行替換空字節(但這樣做會丟失文件名邊界的標識)。
代碼工作甚至用含有換行符的文件名,但只能在系統中sed
和sort
支持(非標準)-z
選項處理空終止輸入「線」 - 這意味着使用GNU sed
和sort
系統(即使在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可以。
但是,如果您不必擔心文件名中的空格? – Gabe 2014-09-06 03:37:26
然後你有重大問題!讓我冥想吧;這是非常不愉快的,無論如何。你在Linux或其他類Unix平臺上嗎? – 2014-09-06 03:39:16
可以假定沒有帶有換行符的文件並解析'ls'輸出。但爲了完整性+1。 – BroSlow 2014-09-06 08:35:10