向每行添加特定单词

向每行添加特定单词

我有一个像这里这样的文件 file.txt

bbb-ccc-cccc#
   aasdf  asdas asdasa fgdg
   asdfa  asfdas  adfaq  asfa
   afdaf  fafa  fafd  afafa
bbb-ccc-cccc#

我想获取以 结尾的单词#,并将其作为第一个单词添加到每一行。

sed 's/bbb-ccc-cccc#/^/' < file.txt > newfile.txt

我提前不知道 # 符号之前的单词,所以我的观点是找到以 结尾的单词#并将其放在每行的开头。对于这个 file.txt 我需要像这样:

bbb-ccc-cccc#
bbb-ccc-cccc#   aasdf  asdas asdasa fgdg
bbb-ccc-cccc#   asdfa  asfdas  adfaq  asfa
bbb-ccc-cccc#   afdaf  fafa  fafd  afafa
bbb-ccc-cccc#

答案1

perl

perl -lpe 'if (/\H+#/) {$word = $&} else {$_ = $word . $_}'

也就是说,如果我们在一行中找到一系列非空白字符 ( \H+) 后跟 a ,我们将使用该序列(正则表达式匹配的内容)作为要插入到下一行开头的单词。#$&

awk与:相同

awk '
  match($0, /[^[:blank:]]+#/) {
    word = substr($0, RSTART, RLENGTH)
    print
    next
  }
  {print word $0}'

sed(使用保留空间来存储单词):

sed '
  /[^[:blank:]]\{1,\}#/ {
    h; # save the line in the hold space
    s//\
&\
/; # put newlines on each side of the matched word
    s/.*\n\(.*\)\n/\1/; # remove every thing but the word
    x; # swap hold and pattern space so that now the hold
       # space contains the word. And branch off:
    b
  }
  # for the other lines:
  G; # append the hold space to the pattern space
  s/\(.*\)\n\(.*\)/\2\1/; # move the word to the beginning'

如果您只想匹配word#行尾的 s,请在上面的所有 3 个命令中替换#为。#$

答案2

使用awk

$ awk '/^[^ ]*#$/ { prefix = $0; print; next } { print prefix, $0 }' file
bbb-ccc-cccc#
bbb-ccc-cccc#    aasdf  asdas asdasa fgdg
bbb-ccc-cccc#    asdfa  asfdas  adfaq  asfa
bbb-ccc-cccc#    afdaf  fafa  fafd  afafa
bbb-ccc-cccc#

这将打印带有前缀的每一行。前缀取自与模式匹配的任何行^[^␣]*#$,即完全由非空格字符组成并以 结尾的行#。打印这些行时没有附加前缀,并且处理将继续处理下一个输入行。

答案3

这是我的解决方案gnu sed

sed '/\(.*\)#/{h;:y;n;/\(.*\)#/b;G;s/\(.*\)\n\(.*\)/\2\1/;by}' test.txt

快速解释:

  • h 将当前缓冲区复制到“保留空间”
  • G 将“保留空间”附加到当前缓冲区(添加需要删除的进位返回)
  • :xxx 是标签
  • bxxx 是 goto。 “b”单独到达脚本的末尾
  • n 打印当前缓冲区并读取下一行

这是我的 bash 解决方案:

while IFS='' read -r x;do if [[ "$x" = *# ]] ; then if [ "$p" = "$x" ]; then p=''; else p="$x"; x=''; fi ; fi; printf '%s%s\n' "$p" "$x";done < test.txt

答案4

在bash中:

#!/bin/bash

# grab one of the lines ending in #
prefix=$(egrep '#$' file | head -1)

cat file | while read line
do
    # if the line ends in a #, just print it
    if [[ $line =~ \#$ ]]
    then
        echo $line
    else
        # print the line prefixed with the $prefix
        printf -- "%s %s\n" "$prefix" "$line"
    fi
done

[[ $line =~ \#$ ]]是一个正则表达式 if 语句,与egrep.如果您的 shell 不喜欢它,您可以将其替换为if egrep -q '#$' <<< line; then.

相关内容