在另一個目錄中遞歸地“查找”包含字元串和符號連結文件的文件名
我正在嘗試對我正在處理的項目中的一組特定文件進行符號連結。
我希望符號連結的每個文件名中都有一個已知字元串。
這是我到目前為止所擁有的:
ln -s find ~/path/to/src/ -name "*stringtomatch*" find ~/path/to/dest
我在目標中設置了目錄結構以匹配源,但它只是目錄,所以如果為空目標編寫命令更容易,我不介意刪除這些。
更新:
我現在已經接受了一個可行的答案,我想分享一些上下文,以便類似的案例可以更容易地找到解決方案。
我在 Netbeans 中執行大部分編碼。當我為一個項目建構包時,我傾向於命名所有關聯的文件,以便它們具有共同的部分文件名。這使我可以在項目中移動時輕鬆找到自己的封包件。但是,在我目前的項目中,由於涉及大量文件和目錄,這非常耗時。
我現在擁有的是為我自己的每個包定義的單獨項目,它只顯示該包的文件,同時保持主項目層次結構。
通過在主項目中建構使用符號連結到我的封包件的單獨包項目,我有效地創建了我認為是完美的解決方案,在目前形式的 Netbeans IDE 中似乎沒有可用的解決方案。
每個子項目只允許我處理僅與自身相關的文件子集,這確實使我在鍵盤上的時間更有效率。
我相信 Eclipse 內置了這個功能,雖然我沒有 Eclipse。
因此,儘管是一種妥協,但我相信 Netbeans 的這種解決方法與我今天可以實現的一樣乾淨。這是一個巨大的好處,它也能正常工作,如果不是比我預期的更好的話。
我曾期望在編輯子項目後手動執行主同步。情況並非如此,主站仍然保持自動同步。
我創建了一個簡短的腳本來執行此操作,輸出很好,應該很容易檢查結果。它不需要創建目標目錄結構。使用如下:
$ ./recursive-symlink.sh --help Usage: ./recursive-symlink.sh <source_path> <dest_path> <find_args...>
為了顯示它的用法,假設我在開始時有以下文件/目錄:
├── recursive-symlink.sh* └── src/ ├── dir1/ │ ├── file_A_misc.txt │ └── file_B_sub.txt ├── dir3/ │ ├── file_A3.txt │ ├── file_C.txt │ └── subsub_dir/ │ ├── file_Asubsub.txt │ └── file_D.txt ├── dir_A/ │ └── should_be_empty.dat ├── file_A.txt └── file_B.txt
如果我執行:
$ find -name '*_A*' ./src/file_A.txt ./src/dir3/file_A3.txt ./src/dir3/subsub_dir/file_Asubsub.txt ./src/dir_A ./src/dir1/file_A_misc.txt
我可以看到哪些文件將被連結。然後我像這樣執行腳本:
$ ./recursive-symlink.sh src/ dest/ -name '*_A*' src/file_A.txt mkdir: created directory 'dest' 'dest/file_A.txt' -> '../src/file_A.txt' src/dir3/file_A3.txt mkdir: created directory 'dest/dir3' 'dest/dir3/file_A3.txt' -> '../../src/dir3/file_A3.txt' src/dir3/subsub_dir/file_Asubsub.txt mkdir: created directory 'dest/dir3/subsub_dir' 'dest/dir3/subsub_dir/file_Asubsub.txt' -> '../../../src/dir3/subsub_dir/file_Asubsub.txt' src/dir_A 'dest/dir_A' -> '../src/dir_A' src/dir1/file_A_misc.txt mkdir: created directory 'dest/dir1' 'dest/dir1/file_A_misc.txt' -> '../../src/dir1/file_A_misc.txt'
我的最終狀態將是:
├── recursive-symlink.sh* ├── src/ │ ├── dir1/ │ │ ├── file_A_misc.txt │ │ └── file_B_sub.txt │ ├── dir3/ │ │ ├── file_A3.txt │ │ ├── file_C.txt │ │ └── subsub_dir/ │ │ ├── file_Asubsub.txt │ │ └── file_D.txt │ ├── dir_A/ │ │ └── should_be_empty.dat │ ├── file_A.txt │ └── file_B.txt └── dest/ ├── dir1/ │ └── file_A_misc.txt -> ../../src/dir1/file_A_misc.txt ├── dir3/ │ ├── file_A3.txt -> ../../src/dir3/file_A3.txt │ └── subsub_dir/ │ └── file_Asubsub.txt -> ../../../src/dir3/subsub_dir/file_Asubsub.txt ├── dir_A -> ../src/dir_A/ └── file_A.txt -> ../src/file_A.txt
您可以看到該
dest
目錄以及所有遞歸子目錄都是自動創建的,並且在該dest
目錄上,只有與該*_A*
模式匹配的文件被連結。這裡的腳本原始碼:
#!/bin/bash verbose='-v' # you may comment this line if [ "$1" == '-h' ] || [ "$1" == '--help' ] || [ $# -lt 3 ] then echo "Usage:" echo " $0 <source_path> <dest_path> <find_args...>" exit fi src="${1%/}" ; shift dest="${1%/}" ; shift relflag='' ; [ "${src:0:1}" != '/' ] && relflag='-r' find "$src" \( "$@" \) -print0 | while IFS= read -r -d '' f do base_fname="${f#$src}" [ "$verbose" ] && echo "${f}" dest_ln="$dest/${base_fname#/}" dest_dir="$(dirname "$dest_ln")" mkdir -p $verbose "$dest_dir" ln $relflag -s $verbose -t "$dest_dir" "$f" [ "$verbose" ] && echo done
如果您已經在目標位置創建了必要的目錄,那麼使用
find
and的 GNU 實現xargs
並不難:find ~/path/to/src -name "*stringtomatch*" -printf "%P\0" | xargs -r0 --replace ln -s ~/path/to/src/'{}' ~/path/to/dest/'{}'
輸出刪除了源目錄參數的
-printf "%P\0"
路徑,並以空字節結尾。
xargs
然後讀取find
輸出。
-0
表示要使用的參數是空分隔的。
--replace
告訴 xargs{}
用參數替換(也意味著每個參數執行一個命令)。最後給出了替換參數的命令。