Bash

使用 bash 將基於列的文本文件格式化為樹結構

  • June 8, 2021

是否有一個 Unix/Linux 命令可以打開這個:

AMERICA USA NEW_YORK    AB-100
AMERICA USA NEW_YORK    VF-200
AMERICA USA NEW_YORK    XY-243
AMERICA USA LOS_ANGELES UH-198
AMERICA CANADA  TORONTO UT-876
AMERICA CANADA  TORONTO UT-877
AMERICA CANADA  VANCOUVER   UT-871
AMERICA CANADA  VANCOUVER   UT-872
AMERICA CANADA  VANCOUVER   UT-873
AMERICA MEXICO  MEXICO  OU-098
AMERICA MEXICO  MONTERREY   OU-099
AMERICA MEXICO  MONTERREY   OU-100
EUROPE  FRANCE  PARIS   IV-122
EUROPE  FRANCE  PARIS   AV-112
EUROPE  FRANCE  PARIS   IF-111
EUROPE  FRANCE  PARIS   XX-190
EUROPE  FRANCE  TOULOUSE    TL-654

進入這個:

AMERICA
   USA
       NEW_YORK
           AB-100
           VF-200
           XY-243
       LOS_ANGELES
           UH-198
   CANADA  
       TORONTO 
           UT-876
           UT-877
       VANCOUVER
           UT-871
           UT-872
           UT-873
   MEXICO  
       MEXICO  
           OU-098
       MONTERREY
           OU-099
           OU-100
EUROPE
   FRANCE
       PARIS
           IV-122
           AV-112
           IF-111
           XX-190
       TOULOUSE
           TL-654

對於您的範例:

dir=$(mktemp -d)
sed 's|\t|/|g' file | while read -r line; do mkdir -p "$dir/$line"; done
(cd "$dir"; tree)
rm -r "$dir"

輸出:

.
├── 美國
│ ├── 加拿大
│ │ ├── 多倫多
UT-876
UT-877
溫哥華酒店
UT-871
UT-872
UT-873
│ ├── 墨西哥
│ │ ├── 墨西哥
│ │ │ └── OU-098
│ │ └── 蒙特雷
│ │ ├── OU-099
│ │ └── OR-100
美國
│ ├── LOS_ANGELES
│ │ └── UH-198
│ └── NEW_YORK
│ ├── AB-100
│ ├── VF-200
│ └── XY-243
└── 歐洲
└── 法國
├── 巴黎
AV-112
│ ├── IF-111
│ ├── IV-122
│ └── XX-190
└── 圖盧茲
└── TL-654

使用標準 s的awk腳本awk,保持行的原始順序,並使用數據中的任意數量的列:

awk -F $'\t' '
 function indent (n, i) { for (i=1; i<=n; i++) printf "\t" }

 { for (i=1; i<=NF; i++)
       if ($i != o[i]) {
           printf "%s%s\n", indent(i-1), $i
           o[i] = $i
       }
 }
'

相同的程序邏輯可以在 shell 中實現。對於bash

indent () { ind=$( printf "%*s" "$1" '' ) ; printf "${ind// /$'\t'}" ;}

while IFS=$'\t' read -a f
do
   for ((i=0; i<${#f}; i++))
   do
       if [[ "${f[i]}" != "${o[i]}" ]]
       then
           printf "%s%s\n" "$( indent "$i" )" "${f[i]}"
           o[i]=${f[i]}
       fi
   done
done

注意:因為ksh您必須通過read -a調整read -A

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