sed を使用した分割

sed を使用した分割

私は別れるべきです

[X] ||| you owns the [X,1] ||| you own the [X,1] ||| 1 0.02020 0.07847 0.36788 3 -0.00000 -0.00000

パイプは、2番目と3番目のパラメータが異なる行を出力します。

答え1

@manatworkのコメント/回答の説明:

  • grepバージョン:grep '^[^|]\+|||\(.\+\?|||\)\1'

    • ^: 行の先頭に一致します。
    • [^|]:以下を除くすべての文字と一致します。|
    • \+:前のパターンと1回以上一致します。
    • |||:区切り文字と一致します。
    • \(\): 角かっこ内に一致する値を保存します。\1
    • .: すべての文字と一致
    • \+\?:1回以上、貪欲ではない
    • |||: 区切り文字に戻ります。
    • \1:かっこ内の前に見たテキストと一致します。

    ここでのアイデアは、最初の区切り文字まで行の先頭をスキップし、2番目の区切り文字が終わるまで見つかった値を保存し、2番目の演算子\1(つまり3番目のフィールド)の後にまったく同じ値を持つ行だけを一致させるです。

  • sedバージョン:sed -n '/^[^|]\+|||\(.\+\?|||\)\1/p'

    同じ意味でパターンを表すためにgrep行の先頭と末尾に1を追加し、一致する行を印刷するには末尾に追加のコマンド文字を追加します。/p

  • awkバージョン:awk -F'\\|\\|\\|' '$2==$3'

    • -F'\\|\\|\\|':フィールド区切り記号を示します。|||この場合、エスケープされました。
    • '$2==$3':2番目と3番目のフィールドが同じ入力のみをフィルタリングします。

答え2

私はこのソリューションを好みますawkが、Bashだけを使いたい場合は、私の答えは次のようになります。

foo() 
{ 
    local filename="$1";
    [[ $filename ]] || return 1

    while read -r line; do
        l="${line#*|||}"; a2="${l%%|||*}"
        l="${l#*|||}"; a3="${l%%|||*}"
        [[ $a2 = $a3 ]] && echo "$line"
    done < "$filename"
}

使用法: foo filename.txt

出力例:

rany$ cat > filename.txt
a|||b|||c|||d|||
a|||b|||c|||d|||
a|||E|||E|||d|||
a|||B|||B|||d|||

rany$ foo filename.txt
a|||E|||E|||d|||
a|||B|||B|||d|||

関連情報