Shell

命令替換 grepping ls 輸出導致錯誤

  • May 10, 2015

我正在嘗試使用命令替換製作一個 tar.tgz 文件

有 2012 年 8 月 17 日的備份

-rw-r----- 1 ossec  502 804M Aug 17  2012 BKPMDISINT_i6nir20j.F_bkp
-rw-r----- 1 ossec  502 2.7G Aug 17  2012 BKPSYFINT_i5nir20j.F_bkp
-rw-r----- 1 ossec  502 3.9G Aug 17  2012 BKPMSFFINT_i4nir20j.F_bkp
-rw-r----- 1 ossec  502  28M Aug 17  2012 c-651746692-20120817-00
-rw-r----- 1 ossec  502 2.0G Aug 17  2012 ALG_KLPFINT_ianir576.alg
-rw-r----- 1 ossec  502 1.5G Aug 17  2012 ALG_KLPFINT_i8nir576.alg
-rw-r----- 1 ossec  502  37M Aug 17  2012 ALG_KLPINT_ibnir64h.alg
-rw-r----- 1 ossec  502 2.2G Aug 17  2012 ALG_KLPFINT_i9nir576.alg
-rw-r----- 1 ossec  502  28M Aug 17  2012 c-651746692-20120817-01
-rw-r----- 1 ossec  502  27M Aug 17  2012 ctrl_170803

所以我需要對它們進行焦油處理。我用了這個命令

tar -zcvf DB-Backup-17082012.tgz $(ls -lrth|grep “8 月 17 日”)

但它給了我這個錯誤

tar: You may not specify more than one `-Acdtrux' option
Try `tar --help' or `tar --usage' for more information.

你的方式

您當然可以做您想做的事,但考慮到某些文件的名稱中可能包含空格,這可能很危險。這是一種方法。

$ tar -zcvf DB-Backup-17082012.tgz $(ls -lrth|grep "Aug 17"|awk '{print $9}')

這將擺脫您從中獲得的所有其他列數據,ls -lrth而只為您提供文件名。

使用 find & tar:方法 #1

您可以使用 Unixfind命令獲取在給定日期最後修改的所有文件的列表,並將此列表通過管道傳輸到tar如下:

$ find . -type f -newermt 2012-08-17 ! -newermt 2012-08-18 -print0 | \
  xargs -0 tar zcvf DB-Backup-17082012.tgz

上面只會找到上次修改時間為 2012-08-17 但沒有更新的文件。-print0告訴 find 使用空字元 ( \0) 拆分它輸出的文件,並獲取這些文件中的每xargs -0一個並建構tar一次批量添加文件的呼叫。

這可能是執行此操作的性能最低的方法。

**注意:**如果您有超過可以作為命令行參數傳遞給tar命令的內容,此方法也存在失去文件的風險。

使用 find & tar:方法 #2

-print0和是多餘的xargs -0,您可以使用它find來生成列表並tar直接呼叫:

$ find . -type f -newermt 2012-08-17 ! -newermt 2012-08-18 \
  -exec tar zcvf DB-Backup-17082012.tgz {} \+

find 上面的{} \+論點將做兩件事。將{}替換每個文件的名稱,因為find在呼叫時在此位置找到它,tar\+告訴find在呼叫之前在命令行上繼續放置盡可能多的文件tartar如果您有 100 個文件要添加到其中,這可以節省您呼叫100 次的時間。

參考

如果你這樣做$(ls -lrth|grep "Aug 17"),你會得到整行,而不僅僅是作為參數的文件名tar,這樣就行不通了。一般來說,您不應該解析.ls

如果您有相對較新版本的 Gnu find ( >= v4.3.3 ),您可以做什麼是

find . -maxdepth 1 -newermt 20120817T0000 -not -newermt 20130818T0000 -print0 \
   | cpio --create --null  --format=ustar \
   | gzip > DB-Backup-17082012.tgz

如果您find不支持-newermt,您可以創建兩個帶有這些日期時間戳的文件,然後使用-newer。當然你也可以使用-daystart -mtime ,但你需要計算天數(或使用試錯法)。

我的一項建議是在 YYYYMMDD 格式的文件中使用日期。如果您有多個文件以截至日期的相同字元串開頭,則第一個更好,第二個類似 05062012 的文件會根據查看文件名的人而模棱兩可(6 月 5 日(歐洲)或 5 月 6 日(美國)) . 所以雖然 1708 必須是 8 月 17 日,但我會呼叫該文件DB-Backup-20120817.tgz

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