使用 find 製作目錄副本
我有一個目錄,裡面有一堆子目錄。因此
/usr/local/src/ccl/ccl-1.8/x86-headers$ ls elf gl gmp gnome2 gtk2 jni libc
這些目錄中的每一個都有一個進一步的子目錄
C
,其中包含一個文件populate.sh
。我想創建一組具有相同結構的並行子目錄,但在目錄名稱後附加一個隨機值(隨機值在所有情況下都應該相同),並且只包含帶有populate.sh
文件的 C 子目錄。這些目錄包含文件之外的其他populate.sh
文件。這是一個makefile,所以為了簡單起見應該使用標準的unix utilties。我正在考慮使用
-exec
標誌查找,或者可能xargs
會起作用,但是我無法理解文件,而且我對 shell 腳本編寫經驗很少。Perl 可能會工作,但我沒有使用過它,並且不想在這裡使用它。我過去一直在使用類似
mktemp -u --tmpdir=.
生成隨機字元串的東西,但這並不理想,所以我願意接受其他建議。理想情況下,我想要一個看起來像libc.tmp_xw3st
. IE。tmp_
後跟一個 5 位字母數字字元串。到目前為止,我已經有了一種獲取頂級目錄列表的方法。:-)
find . -maxdepth 1 -type d -print0 ../gmp./jni./gl./elf./libc./gtk2./gnome2
更完整的目錄列表在這篇文章的末尾。總而言之,我想創建其他目錄,例如
x86-headers/libc.tmpvalue
,其中僅包含進一步的文件x86-headers/libc.tmpvalue/C/populate.sh
。一種可能的方法的草圖是分兩步處理這個問題,如下所示:
第 1 步:使用 遍歷頂級目錄列表
find
,並創建相應的目錄結構,例如dirname.tmpvalue/C/
usingexec
或管道到xargs
和 usingmkdir -p
。第 2 步:再次執行頂級目錄列表並 cp
populate.sh
進入C
子目錄。這有點草率,因為理論上目錄列表可能在兩次呼叫之間發生了變化find
,但在這種情況下這不是問題。/usr/local/src/ccl/ccl-1.8/x86-headers$ ls -laR [...] ./jni: total 96 drwxr-sr-x 3 faheem staff 4096 Jul 31 00:53 . drwxr-sr-x 9 faheem staff 4096 Jul 31 00:53 .. drwxr-sr-x 2 faheem staff 4096 Jul 31 00:53 C -rw-r--r-- 1 faheem staff 19535 Jul 31 00:53 constants.cdb [more .cdb files] ./jni/C: total 12 drwxr-sr-x 2 faheem staff 4096 Jul 31 00:53 . drwxr-sr-x 3 faheem staff 4096 Jul 31 00:53 .. -rw-r--r-- 1 faheem staff 148 Jul 31 00:53 populate.sh ./libc: total 1276 drwxr-sr-x 3 faheem staff 4096 Jul 31 00:53 . drwxr-sr-x 9 faheem staff 4096 Jul 31 00:53 .. drwxr-sr-x 2 faheem staff 4096 Jul 31 00:53 C -rw-r--r-- 1 faheem staff 593125 Jul 31 00:53 constants.cdb [more .cdb files] ./libc/C: total 20 drwxr-sr-x 2 faheem staff 4096 Jul 31 00:53 . drwxr-sr-x 3 faheem staff 4096 Jul 31 00:53 .. -rwxr-xr-x 1 faheem staff 10544 Jul 31 00:53 populate.sh
這不是 的工作
find
,因為不涉及遞歸。for x in */C/populate.sh; do mkdir -- "${x%%/*}$suffix" mkdir -- "${x%%/*}$suffix/C" cp -p -- "$x" "./${x%%/*}$suffix/C" done
如果您不想保留文件的修改時間,請刪除
-p
選項。cp
要生成隨機後綴,BSD/Linux
mktemp
是可移植的。suffix=$(mktemp -u tmp_XXXXX)
如果你想要一些看起來有點隨機且符合 POSIX 的東西,這會給出一個字元串,該字元串每秒都會發生變化,並且會因位置而異;僅使用 POSIX 工具真的不能做得更好:
suffix=$({ hostname; pwd; date; } | cksum | uuencode -m /dev/stdin | awk 'NR==2 {print substr($0,3,5)}')
如果將此程式碼放在 makefile 中,請記住:
- 加倍所有
$
跡象;- 將所有程式碼放在一行上,
;
而不是使用分隔 shell 指令(您可以使用反斜杠+換行符+製表符在 makefile 中放置換行符,但刪除該序列以建構 shell 命令);- 以 開頭的 shell 片段
set -e
,以便在出現任何錯誤時中止。