使用sed或awk单行引用行的一部分

时间:2014-05-29 23:17:36

标签: bash awk sed

使用sedawk

按如下方式转换输入文字

输入文件:

       113259740 QA Test in progress
       219919630 UAT Test in progress

预期产出:

       113259740 'QA Test in progress'
       219919630 'UAT Test in progress'

7 个答案:

答案 0 :(得分:3)

使用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

答案 1 :(得分:1)

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

答案 2 :(得分:1)

你也可以尝试这个GNU sed命令,

sed -r "s/^( +) ([0-9]+) (.*)$/\1 \2 '\3'/g" file
  • ^( +),在起点处捕获一个或多个空格并将其存储在一个组(1)中。

  • ([0-9]+) - 在开始处捕获一个或多个空格后,接下来它匹配一个空格,然后获取该空间旁边的所有数字,然后将其存储在一个组中(2)。

  • (.*)$ - 获取数字旁边的所有字符,直到最后一个字符,然后将其存储在一个组中(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'

答案 3 :(得分:0)

您可以通过利用bash等大多数shell中涉及的分词功能来执行此操作。为了避免在最终结果中使用额外的单引号,您可以使用sed将其删除。这也将修剪i之前,i和j之间以及j之后的任何额外空格。

cat file.txt | sed "s/'//g" | while read i j; do echo "$i '$j'"; done

在这里,我们将第一个单词输入变量i,其余单词输入j。

答案 4 :(得分:0)

awk解决方案:

awk -v q="'" '{ f1=$1; $1=""; print f1, q substr($0,2) q }' file
  • awk按空格将每个输入行拆分为字段(默认行为)。
  • -v q="'"定义了包含单引号的awk变量q,以便更容易在awk程序中使用单引号,这是单引号作为一个整体。
  • f1=$1保存第一个字段供以后使用。
  • $1==""有效地删除了输入行中的第一个字段,最初引用整个输入行的$0包含一个空格,后跟行的其余部分(严格来说,使用输出字段分隔符OFS重新连接字段,默认为空格;由于第1个字段现在为空,因此生成的$0以单个空格开头,后跟所有剩余字段每个空间。)
  • print f1, q substr($0,2) q然后打印保存的第一个字段,然后打印一个空格(OFS),由于,,然后是该行的其余部分(初始空格被{{{ 1}})用单引号括起来(substr())。

请注意,此解决方案规范化空白:

  • 删除了前导和尾随空格
  • 长度大于1的内部空白被压缩为单个空格。

答案 5 :(得分:0)

由于帖子标有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'

答案 6 :(得分:0)

以下是使用awk

执行此操作的简单方法
awk '{sub($2,v"&");sub($NF,"&"v)}1' v=\' file
       113259740 'QA Test in progress'
       219919630 'UAT Test in progress'

它不会更改文件的格式。