txt
に変換したい形式のファイルがありますcsv
。各フィールドの間にスペースブロックがあります。各フィールド間のスペースの数は等しくありません。
3つ以上のスペースを持つブロックをsedまたはawkを使用してに置き換えるコマンドはありますか,
?空白が 2 つしかない場合は、置き換えられるデータの二重スペースを避けるために無視する必要があります。,
入力する:
A_DRIVERLICENSENUMBER_ A_PRIORADDRESS2_ A_MONTHLYRENT_ A_EMPLOYEEID_ A_WORKPHONESPECIALINSTR_ A_REFDETAIL_ A_VERBALPLEDGE
input example,input2 example
出力:
A_DRIVERLICENSENUMBER_,A_PRIORADDRESS2_,A_MONTHLYRENT_,A_EMPLOYEEID,A_WORKPHONESPECIALINSTR_,A_REFDETAIL_,A_VERBALPLEDGE
input example,input2 example
インターネット上でこれを行う方法が見つかりません。ここで誰かが私を助けてくれると確信しています。
答え1
あなたは試すことができます:
sed -E 's/[[:space:]]{3,}/,/g' file
または
perl -pe 's/\s{3,}/,/g' file
答え2
POSIX awkを使用してください。
$ awk -F' {3,}' -v OFS=',' '{$1=$1} 1' file
A_DRIVERLICENSENUMBER_,A_PRIORADDRESS2_,A_MONTHLYRENT_,A_EMPLOYEEID_,A_WORKPHONESPECIALINSTR_,A_REFDETAIL_,A_VERBALPLEDGE,
input example,input2 example
または、awkを使用して3つのスペースをハードコーディングし、+
FSにaを使用します。
awk -F' +' -v OFS=',' '{$1=$1} 1' file
有効なCSV出力(行ごとに同じ数のフィールド)が必要な場合は、最初の行にすべてのフィールドが含まれているとします。
$ awk -F',| {3,}' -v OFS=',' 'NR==1{nf=NF} {$nf=$nf} 1' file
A_DRIVERLICENSENUMBER_,A_PRIORADDRESS2_,A_MONTHLYRENT_,A_EMPLOYEEID_,A_WORKPHONESPECIALINSTR_,A_REFDETAIL_,A_VERBALPLEDGE,
input example,input2 example,,,,,,
または:
$ awk -F' {3,}' -v OFS=',' 'NR==1{nf=NF} {for (i=1; i<=nf; i++) $i="\"" $i "\""} 1' file
"A_DRIVERLICENSENUMBER_","A_PRIORADDRESS2_","A_MONTHLYRENT_","A_EMPLOYEEID_","A_WORKPHONESPECIALINSTR_","A_REFDETAIL_","A_VERBALPLEDGE",""
"input example,input2 example","","","","","","",""
,
入力の既存のsをフィールド区切り文字として扱う必要があるかどうかによって異なります。
答え3
あなたから始めましょうサンプルファイル、あなたはそれを使用することができますミラー6そして走る
mlr --ifs-regex " +" --csvlite --ragged cat input.txt
得るために
A_DRIVERLICENSENUMBER_,A_PRIORADDRESS2_,A_MONTHLYRENT_,A_EMPLOYEEID_,A_WORKPHONESPECIALINSTR_,A_REFDETAIL_,A_VERBALPLEDGE,
input example,input2 example,,,,,,,
いくつかの注意:
--ifs-regex " +"
フィールド区切り記号として3つ以上のスペース設定を使用してください。ragged
、データ行にヘッダー行より少ない数のフィールドがある場合、残りのキーは空の文字列で埋められます。データ行にヘッダー行よりも多くのフィールドがある場合は、暗黙的なヘッダーのように整数フィールドラベルを使用してください。
最後の空のフィールドを削除する場合
mlr -N --ifs-regex " +" --csvlite --ragged remove-empty-columns input.txt
2行目の,
フィールド区切り文字が最初に来たら、すべてのものを正規化し、同じ区切り文字を持つように出力をMillerに渡す必要があります。
sed -r 's/,/ /g' input.txt | mlr -N --ifs-regex " +" --icsvlite --ocsv --ragged remove-empty-columns
出力は正しい正のフィールド区切り文字を持つ正しいcsvです。
A_DRIVERLICENSENUMBER_,A_PRIORADDRESS2_,A_MONTHLYRENT_,A_EMPLOYEEID_,A_WORKPHONESPECIALINSTR_,A_REFDETAIL_,A_VERBALPLEDGE
input example,input2 example,,,,,
答え4
本当にタイトルのみを変更したい場合は、最初の行の空白に似た文字をすべてコンマで置き換えることができます。
$ sed '1s/[[:space:]]\{1,\}/,/g' file
A_DRIVERLICENSENUMBER_,A_PRIORADDRESS2_,A_MONTHLYRENT_,A_EMPLOYEEID_,A_WORKPHONESPECIALINSTR_,A_REFDETAIL_,A_VERBALPLEDGE,
input example,input2 example
不要な末尾のカンマも削除するには、次のようにします。
$ sed -e '1s/[[:space:]]\{1,\}/,/g' -e '1s/,$//' file
A_DRIVERLICENSENUMBER_,A_PRIORADDRESS2_,A_MONTHLYRENT_,A_EMPLOYEEID_,A_WORKPHONESPECIALINSTR_,A_REFDETAIL_,A_VERBALPLEDGE
input example,input2 example
これらのsed
コマンドは、入力データの最初の行と見なされる入力データのヘッダー行のみを変更します。残りのデータは変更されていません。
sed
最後のコマンドをほぼ文字通り翻訳すると、awk
次のようになります。
$ awk 'NR == 1 { gsub(/[[:space:]]+/, ","); sub(/,$/, "") }; 1' file
A_DRIVERLICENSENUMBER_,A_PRIORADDRESS2_,A_MONTHLYRENT_,A_EMPLOYEEID_,A_WORKPHONESPECIALINSTR_,A_REFDETAIL_,A_VERBALPLEDGE
input example,input2 example
...しかし、次のように短縮できます。awk
空白文字で最初の行を分割し、コンマで区切られたレコードに再フォーマットします。
$ awk -v OFS=, 'NR == 1 { $1=$1 }; 1' file
A_DRIVERLICENSENUMBER_,A_PRIORADDRESS2_,A_MONTHLYRENT_,A_EMPLOYEEID_,A_WORKPHONESPECIALINSTR_,A_REFDETAIL_,A_VERBALPLEDGE
input example,input2 example
どちらの場合も、最初の行を除く他の入力行は変更されません。