簡體   English   中英

如何從路徑中刪除最短的子路徑?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM