0

リストとサブリストを含むファイルがあり、コマンド ライン ツールを使用して最長のサブリストを抽出したいと考えています。

ファイルの例:

* Item1
** SubItem1
** ...
** SubItemN

* Item2
** SubItem1
** ...
** SubItemN

* ...
** ...

* ItemN
** SubItem1
** ...
** SubItemN

これが簡単にできるかどうか知りたいのですが、それ以外の場合は Perl スクリプトを書きます。

4

3 に答える 3

3

Perl ワンライナー:

perl -00 -ne '$n=tr/\n/\n/; if ($n>$m) {$m=$n; $max=$_}; END {print $max}' file

bashを使用するだけです:

max=0
while read bullet thingy; do
    case $bullet in
         "*") item=$thingy; count=0 ;;
        "**") ((count++)) ;;
          "") (( count > max )) && { max_item=$item; max=$count; } ;; 
    esac
done < <(cat file; echo)
echo $max_item $max

<(cat file; echo)部分は、ファイルの最後の行の後に空白行があることを確認することです。これにより、最後のサブリスト グループを最大値と比較できます。

それはカウントを保持するだけです。最大のサブリストに項目を保存するには:

max=0
while read bullet thingy; do
    case $bullet in
         "*") item=$thingy; unset sublist; sublist=() ;;
        "**") sublist+=($thingy) ;;
          "") if (( ${#sublist[@]} > max )); then
                  max=${#sublist[@]}
                  max_item=$item
                  max_sublist=("${sublist[@]}")
              fi
              ;;
    esac
done < <(cat file; echo)
printf "%s\n" "$max_item" "${#max_sublist[@]}" "${max_sublist[@]}"

sudo_O の例を使用する場合、これは出力します

letters
6
a
b
b
d
e
f
于 2013-01-04T15:47:29.020 に答える
1
$ cat file    
* letters
** a
** b
** b
** d
** e
** f

* colors 
** red
** green
** blue

* numbers
** 1
** 2
** 3
** 4
** 5

tacを使用してファイルを逆にして、各サブリストの長さを表示しますawk

$ tac file | awk '/^\*\*/{c++}/^\*[^*]/{print c,$2;c=0}'
5 numbers
3 colors
6 letters

最大のサブリストのみの長さを表示:

$ tac file | awk '/^\*\*/{c++}/^\*[^*]/{if(c>m){m=c;l=$2}c=0}END{print m,l}'
6 letters
于 2013-01-04T15:11:12.163 に答える
0
cat file.txt | grep -nE "^\*[^\*].*" | cut -d ":" -f 1,1 | tee tmp | awk 'NR==1{s=$1;next}    {print $1-s;s=$1}' > tmp2
echo 0 >> tmp2
res=`paste tmp tmp2 | sort -nrk 2,2 | head -n 1`
line=`echo "$res" | cut -f 1,1`
ln=`echo "$res" | cut -f 2,2`
cat file.txt | tail -n +$line | head -n $ln
rm tmp tmp2

間違いなくより短い解決策があります:)

于 2013-01-04T15:00:47.820 に答える