グローバル文字を尊重するComm / Diff(または代替):これは可能ですか?

グローバル文字を尊重するComm / Diff(または代替):これは可能ですか?

「グローバル」構文を特に後続の文字グローブに制限するには、*次の手順を実行します。

// foo.txt
foo.*
biz

// bar.txt
bar
foo.bar

私は書きたい:

diff <(sort -u foo) <(sort -u bar)

# alternatively
comm -3 <(sort -u foo) <(sort -u bar)

これにより、次のものが返されます。

# diff
> bar
< biz

# comm
bar 
biz

これは地元で可能ですか?

ベストアンサー1

bar.txtパターンと一致しないのすべての行を報告するには、次のようにします。foo.txtzsh

unique_lines=(${(fu)"$(<bar.txt)"})
unique_patterns=(${(fu)"$(<foo.txt)"})
pattern="(${(j[|])unique_patterns})"

print -rC1 -- ${unique_lines:#$~pattern}

または、一度にすべての作業を実行してください。

print -rC1 -- ${${(fu)"$(<bar.txt)"}:#(${(j[|])~${(fu)"$(<foo.txt)"}})}
  • $(<file)$file末尾の改行文字の後にストライプコンテンツに展開されるkshに似た演算子です。
  • ${(flags)param}使用パラメータ拡張フラグ拡張に影響を与えますparam
  • f改行で区切られたフラグ(ここでは空ではない行のリストに展開されます)
  • u(uniq):重複したアイテムを削除します。したがって、${(fu)"$(<foo.txt)"}空でない一意の行に展開されます。foo.txt
  • ${array:#pattern}$arrayパターンと一致しない要素に展開されます。ここのスキーマは次のように構成されています。
  • ${(j[|])unique_patterns}要素$unique_patternsはに接続されます|。だから私たちはパターンで終わります(line1|line2|...)
  • inを使用すると、変数が展開されたときにワイルドカード文字がワイルドカード文字として扱われます~$~pattern

ワイルドカード構文はzshワイルドカード構文です。これはextendedglob、、、...などの一部のシェルオプションの影響を受けますkshglobnocasematch

では、bash次のことができます。

shopt -s extglob
pattern="@($(sort -u foo.txt | paste  -sd '|' -))"
sort -u bar.txt |
  while IFS= read -r line; do
    [[ $line = $pattern ]] || printf '%s\n' "$line"
  done

今回は、ksh88の構文に似たbash extglobワイルドカード構文を使用します。

行の順序はbar.txt最終的に変わります。

おすすめ記事