3

私はこれを試みるためにsepを使用してきました、基本的に私は同じ行の適度な量を含むテキストファイルを持っています例えば

4444 username "some information" "someotherinformation" "even more information"

引用符内のスペースをアンダースコアに置き換える必要があるので、次のようになります

4444 username "some_information" "someotherinformation" "even_more_information"

現在、引用された情報を分離することができました

sed 's/"\([^"]*\)"/_/g' myfile.txt

続行する方法についてのアドバイスはありますか?

4

4 に答える 4

6
sed -r ':a; s/^((([^"]*"){2})*[^"]*"[^" ]*) /\1_/;ta'
4444 username "some_information" "someotherinformation" "even_more_information"

また

sed ':a; s/^\(\(\([^"]*"\)\{2\}\)*[^"]*"[^" ]*\) /\1_/;ta'
4444 username "some_information" "someotherinformation" "even_more_information"
  • :a- ループのラベル「a」
  • s///- 置換を実行します
  • ^(- 検索文字列全体を行頭に固定します
  • (([^"]*"){2})*- (グループ 1 で) ゼロ以上の非引用符の 2 つのセットとそれに続く引用符 (ゼロ回以上) をキャプチャします。
  • [^"]*"- ゼロ個以上の非引用符が続き、その後に引用符が続きます
  • [^" ]*- スペースまたは引用符ではない 0 個以上の文字が続く
  • )- 固定されたシーケンスを終了し、置換に必要なスペースを探します
  • \1- キャプチャされたグループとアンダースコアを一致したシーケンスに置き換えます
  • ta- 置換が成功した場合は、ラベルに分岐 (実行を転送) (:aそうでない場合は次の命令に進みます。この場合、この行の処理を終了し、次の命令を読み取り、新しいラウンドの処理を開始します)

これは、引用符で囲まれた最後の文字列でスペースを含む最初のスペースを見つけ、それを置き換えます。次に、もしあれば、その引用符で囲まれた文字列が終了するまで。追加のスペースについても同様です。

次に、スペースを含む次の前の引用符付き文字列...など。

:aこれは、 ...taループの各ステップでパターン スペースがどのように見えるかです。

4444 username "some information" "someotherinformation" "even_more information"

4444 username "some information" "someotherinformation" "even_more_information"

4444 username "some_information" "someotherinformation" "even_more_information"

次に、行の先頭で一致するものを探すために、さらに数回ステップスルーします。

于 2012-05-24T00:47:59.810 に答える
3

編集済み

以前のバージョンでは、不要なスペースが追加されていました。このバージョンは、OPが望んでいることを正確に行います。

これはおそらく、あなたが望むものを手に入れるための最も簡単な方法です.

awk -F'"' '
  BEGIN {
    OFS="\""
  }
  {
    for (i = 2; i < NF; i += 2) {
      gsub(/[ \t]+/, "_", $i)
    }

    print $0
  }
' file > outputFile
于 2012-05-23T23:53:47.493 に答える
1

これはあなたのために働くかもしれません:

echo '4444 username "some information" "someotherinformation" "even more information"' |
sed 's/"[^"]*"/\n&/g;:a;s/\(\n"[^"]*\) /\1_/g;ta;s/\n//g'
4444 username "some_information" "someotherinformation" "even_more_information"
  • \n引用符で囲まれた文字列にマーカー()を追加します。sed 's/"[^"]*"/\n&/g;
  • 引用符で囲まれた文字列内のすべてのスペースを。に置き換えます_:a;s/\(\n"[^"]*\) /\1_/g;ta
  • マーカーを削除します。s/\n//g
于 2012-05-24T08:07:03.143 に答える
0

私は実際に C でこれを行います。これにより、ほとんどの高水準言語よりも文字単位のステート マシンを実行する方が簡単になります。

#include <stdio.h>
int main(void)
{
    int inside_quotes = 0;
    int backslash = 0;
    int c;
    while ((c = getchar()) != EOF) {
        switch (c) {
        case ' ':
            if (inside_quotes)
                c = '_';
            break;
        case '"':
            if (!backslash)
                inside_quotes = !inside_quotes;
            break;
        case '\\':
            if (!backslash)
                backslash = 2;
            break;
        default:
            break;
        }
        if (backslash > 0) backslash--;
        putchar(c);
    }
    return 0;
}

テストもコンパイルもされていません。特に、バックスラッシュの処理はバグが多い可能性があります。

于 2012-05-24T00:01:06.490 に答える