我有一个包含文本的文件,如下所示:
dt=2016-06-30,path=path1,site=US,mobile=1
dt=2016-06-21,path=path2,site=UK,mobile=0
我想将其转换为键值对中带有双引号值的文本,如下所示:
dt="2016-06-30",path="path1",site="US",mobile="1"
dt="2016-06-21",path="path2",site="UK",mobile="0"
如何使用 Sed 或任何其他命令将每个值放在双引号内?
答案1
使用塞德
sed -e 's/=\([^,]*\)/="\1"/g' file.txt
使用awk
awk -F, -v OFS=, '{for (f=1;f<=NF;f++) {sub(/=/,"&\"",$f); sub(/$/,"\"",$f)}; print}' file.txt
或者,更短:
awk -F, -v OFS=, '{for (f=1;f<=NF;f++) {gsub(/=|$/,"&\"",$f)} print}' file.txt
还是更短:
awk -F, -v OFS=, '{for (f=1;f<=NF;f++) {gsub(/=|$/,"&\"",$f)}} 1' file.txt
使用前任
Ex是为文件而设计的编辑,但您可以预览更改,而无需实际将它们保存回文件,如下所示:
ex -sc '%s/=\([^,]*\)/="\1"/g | %p | q!' file.txt
要实际进行更改并将其保存到文件中,请使用:
ex -sc '%s/=\([^,]*\)/="\1"/g | x' file.txt
但是,如果您给出的模式在文件中找不到(例如=
文件中没有任何地方),那么 Ex 将不会自动退出。因此,为了更好的鲁棒性,我通常使用printf
将命令传递给 Ex:
printf '%s\n' '%s/=\([^,]*\)/="\1"/g' %p | ex file.txt
并保存更改:
printf '%s\n' '%s/=\([^,]*\)/="\1"/g' x | ex file.txt
答案2
和perl
$ # unlike sed/awk, newline is still part of input record
$ perl -pe 's/=\K[^,\n]*/"$&"/g' ip.txt
dt="2016-06-30",path="path1",site="US",mobile="1"
dt="2016-06-21",path="path2",site="UK",mobile="0"
$ # or chomp newline and add it back while printing
$ perl -lpe 's/=\K[^,]+/"$&"/g' ip.txt
dt="2016-06-30",path="path1",site="US",mobile="1"
dt="2016-06-21",path="path2",site="UK",mobile="0"
答案3
使用 awk
awk '{gsub(/=/, "=\""); gsub(/,/,"\","); print $0"\""}' < file.txt
答案4
使用磨坊主:
$ mlr put 'for (k,v in $*) {$[k] = "\"".v."\""}' mobile.dat
dt="2016-06-30",path="path1",site="US",mobile="1"
dt="2016-06-21",path="path2",site="UK",mobile="0"