【发布时间】:2015-12-12 04:12:38
【问题描述】:
假设一个多行文件,其中的字符串由一个或多个空格分隔。进一步假设字符串组可以用双引号括起来。
> cat file
foo bar "foobar baz qux"
foo "bar foobar baz" qux
"foo bar foobar" baz qux # multiple whitespaces in this line
如果我希望使用下面列出的 awk 将双引号之外的所有空格替换为单个制表符,我会收到以下信息:
awk '{OFS="\t"; FPAT="([^, ]+)|(\"[^\"]+\")"; $1=$1; print}' file
# foo bar "foobar baz qux" # In this line, strings inside the quote are separated by tabs
# foo "bar foobar baz" qux
# "foo bar foobar" baz qux
问题似乎仅限于以双引号结尾的行。
编辑 1: 为了更好地可视化手头的问题:
awk '{OFS="\t"; FPAT="([^, ]+)|(\"[^\"]+\")"; $1=$1; print}' file | cat -A
# foo^Ibar^I"foobar^Ibaz^Iqux"$
# foo^I"bar foobar baz"^Iqux$
# "foo bar foobar"^Ibaz^Iqux$
编辑 2: 除非输入中存在一定数量的非字母字符或非字母字符的组合,否则答案部分中建议的两个命令似乎都可以正常工作。这是一个例子:
> cat file
foo_bar_baz foo foo_bar . Name=foo;product="bar baz qux"
foo_bar_baz foo foo_bar . Name=foo;product="bar baz qux"
foo_bar_baz foo foo_bar . Name=foo;product="bar baz qux"
> awk -v FPAT='"[^"]*"|[^[:blank:]]+' -v OFS='\t' '{$1=$1} 1' file | cat -A
foo_bar_baz^Ifoo^Ifoo_bar^I.^IName=foo;product="bar^Ibaz^Iqux"$
foo_bar_baz^Ifoo^Ifoo_bar^I.^IName=foo;product="bar^Ibaz^Iqux"$
foo_bar_baz^Ifoo^Ifoo_bar^I.^IName=foo;product="bar^Ibaz^Iqux"$
> awk '{$1=$1}1' OFS='\t' FPAT='"[^"]+"|[^ ]+' file | cat -A
foo_bar_baz^Ifoo^Ifoo_bar^I.^IName=foo;product="bar^Ibaz^Iqux"$
foo_bar_baz^Ifoo^Ifoo_bar^I.^IName=foo;product="bar^Ibaz^Iqux"$
foo_bar_baz^Ifoo^Ifoo_bar^I.^IName=foo;product="bar^Ibaz^Iqux"$
编辑 3: EDIT 2 提出的这个问题在这里进一步讨论:Replacing whitespace with single tab unless in double quotes - Part II
【问题讨论】: