テキストファイルに次の行があります
abc|45|"Do not replace | in this"|0.23
|
二重引用符で囲まれたテキストの文字のみを置き換える方法が必要です。
abc|45|"Do not replace in this"|0.23
この代替操作を実行する多数のファイルと行があります。とにかくシェルスクリプトを使用してこれを達成できますか?
答え1
新しい回答(2022)を使うミラーまず、ヘッダーなしのCSV入力の3番目のフィールドからすべてのパイプシンボルを削除してから、すべてのスペースを折りたたみます。すべての引用は元のテキストのままです。
$ mlr --csv --fs pipe -N --quote-original put '$3 = collapse_whitespace(gsub($3,"[|]",""))' file
abc|45|"Do not replace in this"|0.23
同じことですが、すべてのフィールドを繰り返し、すべての文字列を変更しようとしています。
$ mlr --csv --fs pipe -N --quote-original put 'for (k,v in $*) { is_string(v) { $[k] = collapse_whitespace(gsub(v,"[|]","")) } }' file
abc|45|"Do not replace in this"|0.23
内部編集機能を使用して単一のファイルに適用すると機能します。
mlr -I --csv ... *.csv
...これらのファイルが正しくバックアップされたことを確認した後。
前の回答(2019):
csvformat
以下で使用CSVKit、そしてsed
:
$ csvformat -d '|' file | sed 's/| //' | csvformat -D '|'
abc|45|Do not replace in this|0.23
最初の呼び出しは、csvformat
CSV区切り文字を|
コンマからコンマに変更します。その後、単純な呼び出しでパイプ(およびそれに続くスペース)をテキストから削除できますsed
。その後、もう一度csvformat
呼び出して区切り文字を変更します|
。
最終出力には二重引用符は使用されません。もう必要ないからです。最初は実際のデータの一部ではありませんでしたが、使用されたパイプのためにフィールドを分離するだけでした(元のデータは適切に参照されたCSVファイルでした)。
出力でフィールドを参照しますか?-U1
最終通貨と一緒に使用してくださいcsvformat
。これはすべてのフィールドを参照します。
答え2
単純な置換を使用して、およびで始まるsed
文字列を一致させることができます。"
いいえ含まれている内容を含め、"
グループが表示されるまでキャプチャし、そこ|
から最後まで2番目のグループを一致させます"
。その|
文字が含まれていないため、一致するグループを印刷してください。
sed 's/\("[^"]*\).* |\([^"]*"\)/\1\2/g'
答え3
Rubyには優れたCSVライブラリがあるので、次のように簡単にできます。
ruby -rcsv -e 'CSV.filter(col_sep: "|") {|row| row.each {|field| field.gsub!(/\| /, "")}}' file
答え4
Perlの使用(申し訳ありません:難読化されたコード)
perl -pe 's/".*?"/ $& =~ tr[|][]dr /ge' file
説明する:
perl -pe proc
-proc
すべてのラインに適用s/RE/ f($&) /ge
RE
- 結果として置き換えf(matching string)
tr[|][]dr
-|
翻訳しない(=削除)