各ブロックのフィールドで異なる長さのデータブロックをソートする方法

各ブロックのフィールドで異なる長さのデータブロックをソートする方法

<とマークされているさまざまな行数のデータの集まりを含むRDFファイルがあります/>。各ブロック内に で識別されるフィールドがありますname="some name"name各ブロックの行順序を変更せずに、値に基づいてブロックを並べ替える必要があります。また、各ブロックには数字を持つフィールドがあります。このフィールドの番号を変更する必要があります。1到着N各ブロックの位置合わせに基づいています。

以下は3ブロックの例です。

<RDF:Description RDF:about="rdf:#$CHROME1"
 NS1:name="AAA Carolinas"
  NS1:urlToUse=""
  NS1:whereLeetLB="off"
  NS1:leetLevelLB="1"
  NS1:hashAlgorithmLB="md5"
  NS1:passwordLength="16"
  NS1:usernameTB="user"
  NS1:counter=""
  NS1:charset="a9b0c8d1e7f2g6h3i5j4klmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV123456789"
  NS1:prefix="6%Fl"
  NS1:suffix="I$5g"
  NS1:protocolCB="false"
  NS1:subdomainCB="true"
  NS1:domainCB="true"
  NS1:pathCB="false"
  />
<RDF:Description RDF:about="rdf:#$CHROME2"
 NS1:name="Adobe Forums"
  NS1:urlToUse="adobeforums.com"
  NS1:whereLeetLB="off"
  NS1:leetLevelLB="1"
  NS1:hashAlgorithmLB="md5"
  NS1:passwordLength="12"
  NS1:usernameTB="username"
  NS1:counter=""
  NS1:charset="a9b0c8d1e7f2g6h3i5j4klmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV"
  NS1:prefix=""
  NS1:suffix=""
  NS1:protocolCB="false"
  NS1:subdomainCB="true"
  NS1:domainCB="true"
  NS1:pathCB="false"
  NS1:pattern0="*adobeforums.com*"
  NS1:patternenabled0="true"
  NS1:patterndesc0=""
  NS1:patterntype0="wildcard"
  />
<RDF:Description RDF:about="rdf:#$CHROME3"
 NS1:name="Adorama"
  NS1:urlToUse="adorama.com"
  NS1:whereLeetLB="off"
  NS1:leetLevelLB="1"
  NS1:hashAlgorithmLB="md5"
  NS1:passwordLength="8"
  NS1:usernameTB="username"
  NS1:counter=""
  NS1:charset="a9b0c8d1e7f2g6h3i5j4klmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV"
  NS1:prefix=""
  NS1:suffix=""
  NS1:protocolCB="false"
  NS1:subdomainCB="false"
  NS1:domainCB="true"
  NS1:pathCB="false"
  NS1:pattern0="*adorama.com*"
  NS1:patternenabled0="true"
  NS1:patterndesc0=""
  NS1:patterntype0="wildcard"
  NS1:pattern1="www.adoramapix.com*"
  NS1:patternenabled1="true"
  NS1:patterndesc1=""
  NS1:patterntype1="wildcard"
  />

私が言及した数字は$CHROME上記の例の数字です。私は古いアセンブリ、COBOL、Fortran、Basicプログラマーですが、スクリプトや最新の言語には慣れていません。おそらくBasicプログラムでこれを行うことができますが、可能であればLinuxソリューションが必要です。

答え1

どんなキャラクターがあったらいいですか。または、少なくともいくつかあったらいいですね。ひも- あなたのファイルには決して現れません。私はこれがに該当すると仮定します|。より安全にするには||

次のコマンドを実行します。

sed -n -e H -e '/^ *\/> *$/ { s/.*// X; ;s/\n/||/gp }'あなたのファイル|
        ソート
        オランダバー|
        sed -e 's/ *\([0-9]*\)[^|]*||\(.* RDF:about="rdf:#$CHROME\)[0-9]*/\2\ 1/' -e 's/||/\n/g'

注:これには(おそらく)GNU sedが必要です。

概要

  • sedファイルをソートに適した形式に変換するために使用されます(詳細は以下を参照)。
  • の出力を揃えますsed
  • 行番号を適用(追加)します。適切な数値を生成するコマンドを使用します。私はそれが好きですnl -baが、cat -nそれはうまくいき、おそらく他のオプションがあります。
  • sed行の先頭から行番号を削除して末尾に挿入するために使用されますCHROME。データを元の形式に復元します。

詳細 - 最初のsedコマンド

このsortコマンドは各行をレコードとして扱います。したがって、入力ファイルから各(区切られた)レコードを取得し、すべての行を連結して1つの長い行を作成します。また、nameソートキーを指定しないように、行の先頭に値をコピーします。

  • -n自動印刷を無効にするには、このオプションを使用します。と言った場合にのみ行が印刷されますp

  • Hすべての行で実行します。これにより、現在の行が予約済みスペースに追加されます。論理的にはそれがより合理的かもしれません。コピーその<行を予約済みスペースに追加し(コマンドを使用h)、すべての後続の行を追加します。私はこのアプローチをランダムに選択しました。

    <空の予約スペースに行を追加するため、集計レコードの先頭に追加の改行があることに注意してください。

  • を含む行を探し、オプション/>で前後にスペースを追加します。私たちがそれを見つけると、予約されたスペースに完全な記録があることがわかります。この行でのみ、次のコマンドを実行します。

    • s/.*//パターンスペースを消去します(つまり、線を消去/>)。実際に情報を捨てるわけではありません。行は/>すでに予約済みのスペースに追加されました(なぜならすべて行は予約済みスペースに追加されます)。
    • xパターンスペースを変更してスペースを維持します。これは、保持空間からパターン空間に集約された(追加/接続された)レコードを検索します。前の()コマンドによってs/.*//予約されたスペースが消去されます。
    • s/.*NS1:name="\([^"]*\)/\1&/名前フィールドを見つけて、その値をレコードの先頭にコピーします。引用符付き文字を含む名前が利用可能な場合、この操作は失敗します。内部に。
    • s/\n/||/gpパターンスペースの各改行文字をで置き換えます||。 (これはレコードを行に変換するステップです。)その後、pレコードが印刷されます。

sedサンプルファイルに対して実行すると、最初のコマンドの出力は次のようになります。

AAA Carolinas||<RDF:Description RDF:about="rdf:#$CHROME1"|| NS1:name="AAA Carolinas"||  NS1:urlToUse=""||  NS1:whereLeetLB="off"||  NS1:leetLevelLB="1"||  NS1:hashAlgorithmLB="md5"||  NS1:passwordLength="16"||  NS1:usernameTB="user"||  NS1:counter=""||  NS1:charset="a9b0c8d1e7f2g6h3i5j4klmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV123456789"||  NS1:prefix="6%Fl"||  NS1:suffix="I$5g"||  NS1:protocolCB="false"||  NS1:subdomainCB="true"||  NS1:domainCB="true"||  NS1:pathCB="false"||  />
Adobe Forums||<RDF:Description RDF:about="rdf:#$CHROME2"|| NS1:name="Adobe Forums"||  NS1:urlToUse="adobeforums.com"||  NS1:whereLeetLB="off"||  NS1:leetLevelLB="1"||  NS1:hashAlgorithmLB="md5"||  NS1:passwordLength="12"||  NS1:usernameTB="username"||  NS1:counter=""||  NS1:charset="a9b0c8d1e7f2g6h3i5j4klmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV"||  NS1:prefix=""||  NS1:suffix=""||  NS1:protocolCB="false"||  NS1:subdomainCB="true"||  NS1:domainCB="true"||  NS1:pathCB="false"||  NS1:pattern0="*adobeforums.com*"||  NS1:patternenabled0="true"||  NS1:patterndesc0=""||  NS1:patterntype0="wildcard"||  />
Adorama||<RDF:Description RDF:about="rdf:#$CHROME3"|| NS1:name="Adorama"||  NS1:urlToUse="adorama.com"||  NS1:whereLeetLB="off"||  NS1:leetLevelLB="1"||  NS1:hashAlgorithmLB="md5"||  NS1:passwordLength="8"||  NS1:usernameTB="username"||  NS1:counter=""||  NS1:charset="a9b0c8d1e7f2g6h3i5j4klmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV"||  NS1:prefix=""||  NS1:suffix=""||  NS1:protocolCB="false"||  NS1:subdomainCB="false"||  NS1:domainCB="true"||  NS1:pathCB="false"||  NS1:pattern0="*adorama.com*"||  NS1:patternenabled0="true"||  NS1:patterndesc0=""||  NS1:patterntype0="wildcard"||  NS1:pattern1="www.adoramapix.com*"||  NS1:patternenabled1="true"||  NS1:patterndesc1=""||  NS1:patterntype1="wildcard"||  />

詳細 - 2番目のsedコマンド

  • s/ *\([0-9]*\)[^|]*||\(.* RDF:about="rdf:#$CHROME\)[0-9]*/\2\1/ 線を複数の部分に分割します。

    • 0個以上のスペース。
    • 行番号(0個以上の数字)です。これが\1グループになります。
    • 行番号、value、nameおよび||その後のタブ文字です。
    • ところが記録が上がったRDF:about="rdf:#$CHROME。これが\2グループになります。
    • 前のレコード番号(0個以上の数字)。
    • 暗黙的に残りの記録です。

    RDF:about="rdf:#$CHROME次に、最初の5つの部分を行番号(新しいレコード番号)の合計に置き換えます。残りのレコードは一致しないため、コマンドの影響を受けません。

  • s/||/\n/g||各行を改行文字に置き換えて、ファイル内の元の複数行構造を復元(再生成)します。

確かに、…

...出力をファイルに送信するには、コマンドの最後の行の最後に(つまり、2行目の最後に)追加します。これで移動できます() > your_output_filesedmvyour_output_file元のファイルに。コマンドのオプションを指定することは--output=意味がありません。-osortsort 〜しなければならない行番号を適用するコマンドを入力します。中間ファイルをキャプチャするには、そう言います。

関連情報