Find

從列表中排除最後修改的最後 N 行,文件副檔名以 .gz 結尾

  • July 18, 2022

我想find在 AIX 上使用該命令來排除以 結尾的文件.gz,並且它還必須從列表中排除最後 2 行。例如,在目錄中,我有:

shop14_0_Log0002019754.gz
shop14_0_Log0002019755.gz
shop14_0_Log0002019756.gz
shop14_0_Log0002019757
shop14_0_Log0002019758.gz
shop14_0_Log0002019759.gz
shop14_0_Log0002019760.gz
shop14_0_Log0002019761.gz
shop14_0_Log0002019762

我想通過只檢索未壓縮的文件來獲得下面顯示的輸出,但不包括底部的最後兩個文件:

輸出命令必須實現:

shop14_0_Log0002019757

我可以使用該ls命令排除最後兩行,但是如何通過排除名稱以 結尾的文件來做到這一點.gz?我正在努力尋找 AIX/UNIX 中的方法:

ls -ltr | awk '{print $9} |  sed '$d' |  sed '$d'

使用find,我可以通過.gz從列表中排除來獲得未壓縮的文件列表,但它包括我不想要的最後兩個文件:

find . -type f ! -name '*\.gz'  -print 

上面的find命令返回:

./shop14_0_Log0002019757
./shop14_0_Log0002019762

該文件shop14_0_Log0002019762應從列表中排除,如果shop14_0_Log0002019761也未壓縮,則它也必須從列表中排除。我怎樣才能做到這一點?

如果您使用 bash,並且 100% 確定您的文件名永遠不會包含換行符或空格,您可以執行以下操作:

shopt -s extglob
ls -t !(*gz) | tail -n +3 | while IFS= read -r file; do gzip "$file"; done

shopt -s extglob啟用了擴展的 globbing,這為我們!(*gz)提供了“不以 gz 結尾”。然後,通過使用ls -t,我們按照修改時間排序,最新的在前,tail -n +3意思是“列印從第 3 行開始的所有內容”,因此將跳過前兩個文件。最後,您將其通過管道傳輸while到文件的循環中gzip。或者,您也可以這樣做:

gzip $(ls -t !(*gz) | tail -n +3)"

或者

ls -t !(*gz) | tail -n +3 | xargs gzip

請注意,這只是因為您可以確定您的文件名是健全的。請參閱https://mywiki.wooledge.org/ParsingLsls了解為什麼不建議解析 的輸出。

引用自:https://unix.stackexchange.com/questions/710260