[英]Single-quote part of a line using sed or awk
使用sed
或awk
如下转换输入文本:
输入文件:
113259740 QA Test in progress
219919630 UAT Test in progress
预期产量:
113259740 'QA Test in progress'
219919630 'UAT Test in progress'
使用GNU sed
或BSD(OSX) sed
:
sed -E "s/^( *)([^ ]+)( +)(.*)$/\1\2\3'\4'/" file
^( *)
捕获所有前导空格(如果有) ([^ ]+)
捕获第一个字段(一系列长度至少为1的非空格字符) ( +)
捕获第一个字段之后的空格 (.*)$
匹配行的其余部分,无论它是什么 \\1\\2\\3'\\4'
将每个(匹配的)输入行替换为捕获的前导空格,然后是第一个字段,然后是捕获的第一个字段间空间,然后是单引号的其余部分输入线。 要丢弃前导空格,只需省略\\1
。 注意:
一个支持其他形式的空格 (例如制表符)的通用解决方案 ,包括在第一个字段之后,如下所示:
sed -E "s/^([[:space:]]*)([^[:space:]]+)([[:space:]]+)(.*)$/\\1\\2\\3'\\4'/" file
如果您的sed
版本不支持-E
(或-r
)以支持扩展的正则表达式,请尝试以下使用基本正则表达式的POSIX兼容变体:
sed "s/^\( *\)\([^ ]\{1,\}\)\( \{1,\}\)\(.*\)$/\1\2\3'\4'/" file
并在awk
:
awk '{ printf "%s '"'"'", $1; for (i=2; i<NF; ++i) printf "%s ", $i; print $NF "'"'"'" }' file
说明:
printf "%s '"'"'", $1;
打印第一个字段,后跟一个空格和一个引号( '
) for (i=2; i<NF; ++i) printf "%s ", $i;
打印以下所有字段,保存最后一个字段,每个字段后跟一个空格。 print $NF "'"'"'"
打印最后一个字段,后跟引号( '
) 请注意, '"'"'"
仅用于打印单引号( '
)。另一种方法是在命令行上将引号字符指定为变量:
awk -v qt="'" '{ printf "%s %s", $1, qt; for (i=2; i<NF; ++i) printf "%s ", $i; print $NF qt }' file
您也可以尝试使用此GNU sed
命令,
sed -r "s/^( +) ([0-9]+) (.*)$/\1 \2 '\3'/g" file
^( +)
在开始处捕获一个或多个空格,并将其存储在group(1)中。
([0-9]+)
-在开始处捕获一个或多个空格后,下一个空格将与该空格之后的空格匹配,并获取该空格旁边的所有数字,然后将其存储在group(2)中。
(.*)$
-提取数字旁边的所有字符直到最后一个字符,然后将其存储在group(3)中。
根据需要的输出,所有获取的组都将在替换部分中重新排列。
例:
$ cat ccc
113259740 QA Test in progress
219919630 UAT Test in progress
$ sed -r "s/^( +) ([0-9]+) (.*)$/\1 \2 '\3'/g" ccc
113259740 'QA Test in progress'
219919630 'UAT Test in progress'
您可以利用bash等大多数shell中涉及的单词拆分功能来执行此操作。 为了避免在最终结果中以多余的单引号引起来,您可以仅使用sed将其删除。 这还将修剪i之前,i和j之间以及j之后的所有多余空间。
cat file.txt | sed "s/'//g" | while read ij; do echo "$i '$j'"; done
在这里,我们将第一个单词传递给变量i,其余的传递给j。
awk
解决方案:
awk -v q="'" '{ f1=$1; $1=""; print f1, q substr($0,2) q }' file
awk
用空格将每条输入行拆分为字段(默认行为)。 -vq="'"
定义包含单引号的awk变量q
,以便更轻松地在awk程序中使用单引号,该程序在整体上被单引号引起来。 f1=$1
保存第一个字段供以后使用。 $1==""
有效地从输入行中删除了第一个字段,而保留$0
最初指向整个输入行的$0
,以在其后的其余行中包含一个空格(严格来说,这些字段使用输出字段分隔符OFS
,默认为空格;由于第一个字段现在为空,因此结果$0
以单个空格开头,然后是所有其余字段,每个空格之间用空格隔开。 print f1, q substr($0,2) q
然后打印所保存的第一字段,后跟一个空格( OFS
)由于,
,其次是该行的其余部分(与剥离的初始空间substr()
包含在单引号( q
)。 请注意,此解决方案规范了空格:
由于帖子使用bash
标记,因此这里提供了一种全Bash解决方案,可保留领先的空白空间。
while IFS= read -r line; do
read -r f1 f2 <<<"$line"
echo "${line/$f1 $f2/$f1 $'\''$f2$'\''}"
done < file
输出:
113259740 'QA Test in progress'
219919630 'UAT Test in progress'
这是使用awk
的简单方法
awk '{sub($2,v"&");sub($NF,"&"v)}1' v=\' file
113259740 'QA Test in progress'
219919630 'UAT Test in progress'
它不会更改文件的格式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.