文字列から\ nを削除する方法

文字列から\ nを削除する方法

文字列の列23に\ nがあるタブ区切りのテキストファイルがあり、これは次の行に進みます。

スペースが有効なviでテキストファイルを開くと、DESCR2フィールドの値に文字列を区切る空白行があることがわかります。

文字列はタブで区切られた文字内に含まれており、\ nを削除し、1フィールドにある間に文字列をABC 123に連結しようとします。

私はこれを試しましたが、tr -d '\n' < file.txtすべての行を1行に置き換えます。この列から\n\nを削除したいと思います。

私も試してみましたが、うまくいきませんでしsed 's/\n\n//' file.txtた。 viで\ n \ nを検索して置き換えることができますが、sedを使用すると同じ結果を得ることはできません。

例:

\t"ABC\n
\n
123"\t

希望の出力:

\t"ABC 123"\t

答え1

タブ文字をフィールド区切り文字として使用する正しい形式のCSVファイルがあるようです。示されている例のように、正しく引用されている限り、フィールドに改行を含めることができます。すべてのCSVパーサーはデータを読み取るのに問題はありません。

これらの改行文字を削除するには、次のCSVパーサーを使用できます。csvkit

次のサンプルファイルを使って作業します。

$ cat -t file.csv
col1^Icol2^Icol3
col1^I"ABC

123"^Icol3
col1^Icol2^Icol3

それぞれは^Iタブ文字です。 2行目の2番目のフィールドには2つの連続した改行文字が含まれており、これを単一の空白文字で安全に置き換えようとします。

私はCSVデータをJSON文書に変換するcsvjsonfromを使用しています。csvkitこれにより、データを変更するのに少し簡単になり、jqデータをCSV形式に変換するためにも使用できます。

$ csvjson -t -H file.csv | jq -r '.[] | [ .[] | values |= gsub("\n\n";" ") ] | @csv'
"col1","col2","col3"
"col1","ABC 123","col3"
"col1","col2","col3"

ここで使用されるコマンドは、csvjsonCSVファイルの各行をJSONオブジェクトに変換します。この-tオプションは、入力がタブ文字を区切り文字として使用し、列見出しが-Hないことをツールに通知します。

JSONオブジェクトを配列に入れて読み取り、値を抽出します(元のCSVファイルにはヘッダーがないか、質問で述べたように少なくともないため、データはなどのキーにjq割り当てられます)。スペースを使用して簡単な置換を適用します。連続した改行のすべてのペアを交換します。abcgsub()

gsub()明らかに、上記の正規表現を変更し\n+て、連続した改行文字を単一の空白文字に置き換えることができます。

その後、オペレータは@csvCSV出力形式の配列形式でデータセットを受け取ります。

csvformatデフォルトのフィールド区切り文字をコンマからタブに戻すには-T(タブ区切り出力の場合)および(CSV入力にヘッダーなし)オプションを使用して-H結果をパイプします。

$ csvjson -t -H file.csv | jq -r '.[] | [ .[] | values |= gsub("\n\n";" ") ] | @csv' | csvformat -T -H
col1    col2    col3
col1    ABC 123 col3
col1    col2    col3

csvformat引用が必要なフィールドは自動的に引用されます。

このcsvformatツールも同様ですcsvkit


Noteで作成した中間JSON文書はcsvjson次のとおりです(ローマ化jq)。

[
  {
    "a": "col1",
    "b": "col2",
    "c": "col3"
  },
  {
    "a": "col1",
    "b": "ABC\n\n123",
    "c": "col3"
  },
  {
    "a": "col1",
    "b": "col2",
    "c": "col3"
  }
]

答え2

GoCSVはこれを行うことができます。

TSVをCSVに変換し、改行を置き換えます。

次のTSVファイルから始めて、データをシミュレートしてみましょう。

+--------+--------+--------+--------+--------+
| Col21  | Col22  | DESCR2 | Col24  | Col25  |
+--------+--------+--------+--------+--------+
| data21 | data22 | ABC    | data24 | data25 |
|        |        |        |        |        |
|        |        | 123    |        |        |
+--------+--------+--------+--------+--------+

最初のステップは、TSVをすべてのGoCSVコマンドで使用される形式であるCSVに変換することです。また、DESC2値を含む新しい列を最後に追加し、改行を置き換えました。 -N~である名前新しい列-ティーSPRIGです金型replace必要な関数を使用すると(.DESCR2 | replace「DESCR2列を代替関数に入れます」のように読みます):

gocsv delim   \
    -i "\t"   \
    -o ","    \
    input.tsv | 
  gocsv add                               \
    -n DESCR2_replaced                    \
    -t '{{ .DESCR2 | replace "\n" " " }}' \
  > replaced.csv

.csv 置換

+--------+--------+--------+--------+--------+-----------------+
| Col21  | Col22  | DESCR2 | Col24  | Col25  | DESCR2_replaced |
+--------+--------+--------+--------+--------+-----------------+
| data21 | data22 | ABC    | data24 | data25 | ABC  123        |
|        |        |        |        |        |                 |
|        |        | 123    |        |        |                 |
+--------+--------+--------+--------+--------+-----------------+

新しい列に置き換えて古い列に名前を変更する

_replaced列のデータを正規化した後、選ぶ既存のDESCR2を削除し、新しいDESCR2_replacedを「選択」して置き換えます。それから名前を変更するDESCR2_はDESCR2に置き換えられます。私の例では、6つの列しかないので-氏 索引は、23個以上の列ファイルの索引とは異なります。

gocsv select     \
    -c 1-2,6,4-5 \
    replaced.csv |
  gocsv rename    \
    -c 3          \
    -names DESCR2 \
  > final.csv

最終.csv

+--------+--------+----------+--------+--------+
| Col21  | Col22  | DESCR2   | Col24  | Col25  |
+--------+--------+----------+--------+--------+
| data21 | data22 | ABC  123 | data24 | data25 |
+--------+--------+----------+--------+--------+

TSVに再変換

gocsv delim   \
    -i ","    \
    -o "\t"   \
    final.csv \
  > final.tsv

大きなパイプ

gocsv delim                                \
    -i "\t"                                \
    -o ","                                 \
    input.tsv                              \
| gocsv add                                \
    -n DESCR2_replaced                     \
    -t '{{ .DESCR2 | replace "\n" " " }}'  \
| gocsv select                             \
    -c 1-2,6,4-5                           \
| gocsv rename                             \
    -c 3                                   \
    -names DESCR2                          \
| gocsv delim                              \
    -i ","                                 \
    -o "\t"                                \
> final.tsv

答え3

以下を試しましたかsed ':a;N;$!ba;s/\\n\n/ /g' file.txt

私が見つけたこれ回答では、sedを使用して改行文字を削除し、追加の\\nバックスラッシュを追加して特殊文字をエスケープする方法について詳しく説明します。

答え4

単純な sed 実行にはパターンスペースにいつでも 1 行しか含まれないため、sed 構文は機能しません。 (重複していない場合は同様の)質問には、sedを使用して複数行の編集を処理する方法を説明する答えがあります。ここ。 TLDRは不都合で構文が痛いということです。

同様に、trは常に1行しか表示されないため失敗します。

私の考えでは、複数行を処理する最も簡単な方法はPerlを使用することです。

perl -0777 -pe 's/\n\n/ /igs' file.txt

ここで、-0777はPerlにファイル全体を一致させるように指示しますが、-peは検索して置換するだけです。

このバージョンでは、インライン編集に-iを使用します。

perl -0777 -pe 's/\n\n/ /igs' -i file.txt

編集する: 表示される特殊文字に置き換えるには、正規表現でその特殊文字を正しくエスケープする必要がある場合があります。 \n

関連情報