[英]How to remove the shortiest subpaths from path?
我有一個包含某些目錄結構的字符串。
dirs='Rootdir/
Secondrootdir/
Rootdir/Subdir/
Secondrootdir/Anothersubdir/
Secondrootdir/Thirdsubdir/
Secondrootdir/Anothersubdir/Subsubdir/'
我想過濾它並獲得以下信息:
dirs='Rootdir/Subdir/ Secondrootdir/Thirdsubdir/
Secondrootdir/Anothersubdir/Subsubdir/'
請幫幫我。
也許是這樣的:
dirs="Rootdir/ Secondrootdir/ Rootdir/Subdir/ Secondrootdir/Anothersubdir/ Secondrootdir/Thirdsubdir/ Secondrootdir/Anothersubdir/Subsubdir/"
echo $dirs \
| tr ' ' '\n' \
| sed -e 's#\([^/]\)$#\1/#' \
| sort -r \
| gawk '!index(prev,$0){print;} {prev=$0;}'
這產生
Secondrootdir/Thirdsubdir/
Secondrootdir/Anothersubdir/Subsubdir/
Rootdir/Subdir/
在這里, tr
首先將以空格分隔的輸入分成幾行。 sed
確保每個路徑都以斜杠結尾。 與sort -r
結合使用,結果是,如果路徑p是路徑q的子路徑,則q在排序輸出中排在第一位。 最后, gawk
僅過濾那些不是上一個子路徑的路徑。 由於特定的排序順序,因此可以有效地僅選擇目錄結構的葉子。
除了不錯的@ewcz之外,我提出了一種替代方案,即顯式版本,它不調用外部可執行文件並尊重原始問題中提出的格式:
dirs='Rootdir/
Secondrootdir/
Rootdir/Subdir/
Secondrootdir/Anothersubdir/
Secondrootdir/Thirdsubdir/
Secondrootdir/Anothersubdir/Subsubdir/'
out=()
for d in ${dirs};do
found=0
for db in ${dirs};do
# d is subpath of db
[[ ( "${db}" == "${d}"* ) && (${#db} -gt ${#d}) ]] && found=1 && break
done
[[ $found == 0 ]] && out+=($d)
done
echo ${out[*]}
首先顯示要刪除的行。
您可以刪除所有路徑,在該路徑中還將有相同的路徑,后跟某個文件夾。 當找到path/more/
時,例如刪除以path/
結尾的字符串。
我用"${dirs// }"
修復了以空格結尾的第一行。 對於帶有空格的目錄,解決方案將失敗,但是輸入格式也缺少引號。
sed -n '/\/.*\// s# *\(.*/\)\([^/]*\)/$#\1#p' <<< "${dirs// }" | sort -u
現在,您可以使用進程替換告訴grep
跳過上述命令指定的“文件”中的所有行。
您需要不同的grep
選項: F
將忽略特殊含義, x
將僅匹配完整行, v
將使grep
反轉,並且f
將讀取字符串以從文件中匹配。
grep -Fxvf <(
sed -n '/\/.*\// s# *\(.*/\)\([^/]*\)/$#\1#p' <<< "${dirs// }" | sort -u
) <<< "${dirs// }"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.