我有一个文本文件,每行都有一些定义的字段数,但它们可能因行而异。我想要做的就是在该行字段中的每个值前添加“=”符号。
例如输入文件
A B C D E
P Q R S T U
L M N O
Run Code Online (Sandbox Code Playgroud)
输出文件
=A =B =C =D =E
=P =Q =R =S =T =U
=L =M =N =O
Run Code Online (Sandbox Code Playgroud)
这也只是一个例子,我的文件包含一些字段数超过 20 的行。如何有效地做到这一点。
假设您的字段包含不止一个字母,使用 GNU sed:
sed 's/\</=/g' <<END
foo bar baz
A B C
apple banana cherry
END
Run Code Online (Sandbox Code Playgroud)
=foo =bar =baz
=A =B =C
=apple =banana =cherry
Run Code Online (Sandbox Code Playgroud)
GNU sed 的\<正则表达式构造是一个零宽度的“单词开始”标记(非单词(或行首)和单词字符(您的语言环境中的alnums或下划线)之间的过渡)。所以我们用“=”字符替换每个单词的开头。
(sed regex 参考这里)
一个较短的awk版本:
$ awk 'gsub(/([^ ]+)/,"=&",$0)' file
=A =B =C =D =E
=P =Q =R =S =T =U
=L =M =N =O
Run Code Online (Sandbox Code Playgroud)
解释
我们对每个输入行进行全局替换:
/([^ ]+)/: 匹配每个字段,因为字段由空格分隔,所以这个正则表达式匹配除空格之外的所有内容。
"=&": 对于每个字段,=在它之前添加。
&意义被匹配的字符替换。来自man awk:
gsub(r, s [, t]) For each substring matching the regular expres?
sion r in the string t, substitute the string
s, and return the number of substitutions. If
t is not supplied, use $0. An & in the
replacement text is replaced with the text that
was actually matched. Use \& to get a literal
&. (This must be typed as "\\&"; see GAWK:
Effective AWK Programming for a fuller discus?
sion of the rules for &'s and backslashes in
the replacement text of sub(), gsub(), and gen?
sub().)
Run Code Online (Sandbox Code Playgroud)
更新
对于@glenn jackman 的回答和评论,我添加了一个等效版本perl:
$ perl -pe 's/\b(?=\w)/=$&/g' file
=A =B =C =D =E
=P =Q =R =S =T =U
=L =M =N =O
Run Code Online (Sandbox Code Playgroud)
要在 中执行此操作awk,您可以使用:
awk '{for (i=1;i<=NF;i++) printf "=%s ",$i;printf "\n"}' filename
Run Code Online (Sandbox Code Playgroud)
循环内部NF(字段数)变量,打印每个字段,并在前面添加等号并附加空格,然后在打印所有字段后,打印换行符。