我有一个格式的文件txt
,我想将其转换为csv
.每个字段之间都有空格块。每个字段之间的空格数量并不相同。
是否有使用 sed 或 awk 的命令将具有 3 个或更多空格的块替换为,
.如果只有 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 个空格,然后使用 a+
表示 FS:
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
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
在这两种情况下,我们都避免修改除第一行之外的任何其他输入行。