bashで1つのファイルを繰り返すが、別のファイルの順序に基づいた方法は何ですか?

bashで1つのファイルを繰り返すが、別のファイルの順序に基づいた方法は何ですか?

次のファイルがあるとしますDependencies

Accounts
Blog
Configuration
Contacts
Entities
Faqs
Forms
Galleries
Geo
Globalization
Logs
Media
Navigation
Notifications
Orders
Payment
Places
Pricing
Products
Sales
Seo
Services
Shipment
Social
Subscriptions
Taxonomy
Ticketing

さまざまな方法を使用してこれを繰り返し、各行を変数にして操作を実行できます。

Orderただし、次のような名前の異なるファイルがあります。

Entities
Globalization
Configuration
Accounts
Contacts
Taxonomy
Geo
Media
Places
Products
Services
Orders
Shipment
Payment
Sales
Social

これは、ファイルで指定された順序Dependenciesで行をロードする必要があることを意味します。Orderファイルに行がない場合はOrderリストの最後に移動し、順序は重要ではありません。

dependencies.OrderBy(i => orders.IndexOf(i))C#では、指定された順序で依存関係を簡単に一覧表示できます。

しかし、bashでこれを行う方法がわかりません。

答え1

私は各行が一意でDependenciesあると仮定します。についても同様ですOrder。この仮定はあなたのユースケースに適しているようです。

次のように呼び出します。

grep -xFf Dependencies Order; grep -vxFf Order Dependencies

最初は in と in の行を から順にgrep提供します。DependenciesOrderOrder

2 番目は にあるが にはない行をgrep提供します。これは印刷されていない最初の行です。DependenciesOrderDependenciesgrep

すべての行の合計がDependencies表示されます。

Dependenciesからまたはで繰り返される行が出力Orderに複数回表示されることがありますが、 とまったく同じ数を持たない可能性があるため、一意性の前提が関連しますDependencies。出力の数はgrep印刷位置によって異なります。

答え2

使用awk:

awk '
    FNR == NR {
        words[$0]
        next
    }
    ($0 in words) {
        print
        delete words[$0]
    }
    END {
        for (word in words)
            print word
    }' Dependencies Order

Dependenciesまず、行を連想配列のキーとして読み込みます。words次に行を読み取り、Order文字列がwords配列のキーである場合はそれを印刷して配列からキーを削除します。最後に、残りのすべてのキーがwords印刷されます。

最終行のリストが印刷される順序は、配列のキーが検索される順序によって異なります。したがって固定されないことがありますwords

テスト:

$ awk 'FNR == NR { words[$0]; next } ($0 in words) { print; delete words[$0] } END { for (word in words) print word }' Dependencies Order
Entities
Globalization
Configuration
Accounts
Contacts
Taxonomy
Geo
Media
Places
Products
Services
Orders
Shipment
Payment
Sales
Social
Galleries
Subscriptions
Seo
Faqs
Notifications
Ticketing
Forms
Navigation
Blog
Pricing
Logs

上記のコードは重複を排除します。で重複した項目を保持するには、Dependenciesファイル内の各行を見た回数を追跡し、その行を見た回数を出力します。

awk '
    FNR == NR {
        words[$0]++
        next
    }
    ($0 in words) {
        while (words[$0]-- > 0) print
        delete words[$0]
    }
    END {
        for (word in words)
            while (words[word]-- > 0) print word
    }' Dependencies Order

答え3

zsh代わりにを使用している場合は、bash次のようにして同じindexof()メソッドを使用できます。

order=( ${(f)"$(<Order)"} )
dependencies=(
  /(Ne['
        reply=( ${(f)"$(<Dependencies)"} )
     ']noe['
        REPLY=$order[(ie)$REPLY]
     '])
)

それから:

for dep in $dependencies; do
  ...
done

繰り返してください。

noe[code]変更された値に基づいてglob拡張を数値でソートするには、glob修飾子を使用しますn。 glob拡張(ここに適用されます)は、ファイルラインを修飾子で埋めることによってシードされます(以前はファイルラインで配列を埋めたように)。o$REPLYcode/$replyDependencies$orderOrdere

$order[(ie)$REPLY]ixactに一致する最初の要素のインデックスに展開されます。一致するものがない場合は、1+最後のインデックスです。$order$REPLYee

${a:*b}別の方法は、配列交差集合と減算${a:|b}演算子を使用することです。

order=( ${(f)"$(<Order)"} )
dependencies=( ${(f)"$(<Dependencies)"} )

dependencies=(
  ${order:*dependencies} # elements or $order that are also in $dependencies
  # followed by:
  ${dependencies:|order} # elements of $dependencies that are not in $order
)

関連情報