如何将字符串附加到模式的第一个匹配项中?

时间:2011-07-08 12:08:59

标签: bash sed

当我找到第一个foo模式时添加一个苹果字符串。

输入数据:

foofoo
foobaz
foobez

结果:

apple
foofoo
foobaz
foobez

可以使用bash / sed吗? 感谢

5 个答案:

答案 0 :(得分:2)

不是bash / sed而是perl,这是我的专长。

perl -pE 'say "apple" if /^foo/ and not $seen_foo++'

对于每一行,如果行以“foo”开头并且我们之前没有看到过这样的行,则说“apple”,然后打印该行。

答案 1 :(得分:1)

#!/bin/bash

typeset -i seen_foo=0;
while read line; do
  case "${line}" in
    *foo*)
    let seen_foo++
    [ $seen_foo -eq 1 ] && echo apple
    ;;
  esac
  echo "${line}"
done

将perl的答案翻译成bash 如果将上面的内容保存为/ tmp / x并将输入保存为/ tmp / x1,则可以像这样运行

  

bash / tmp / x<的/ tmp / X1

答案 2 :(得分:1)

我假设,该列表是一个文件(?)。所以只使用 Bash (只是为了好玩,perl的表现力更强大)我会这样做:

#!/usr/bin/env bash

newstr="$1"
filein="$2"
counter=0

while read -r; do
    ((counter++))
    if [[ $REPLY =~ ^foo ]]; then
        printf "%s\n" "$newstr" "$REPLY"
        break # no need to loop anymore
    fi
    printf "%s\n" "$REPLY"
done < "$filein"

# just print the rest of the file
sed -n "$counter,$(wc -l < "$filein")p" "$filein"

像这样使用它:

$ that_script apples file

灵感来自我在a similar question

中的回答

注意:这只是查看字符串是否以 foo开头。通过更改下面的行,将您自己的模式放置到适合您的模式:

if [[ $REPLY =~ ^foo ]]; then

答案 3 :(得分:1)

Pure Bash:

nl=$'\n'
str='foofoo
foobaz
foobez
'
echo "${str/foo/apple${nl}foo}"

答案 4 :(得分:1)

使用'sed':

$ cat infile

foofoo
foobaz
foobez

$ cat script.sed

## The pattern 'foo' found in the line.
/foo/ {
        ## Check hold space, case of being blank, it's the first pattern 'foo' so
        ## I will print the word 'apple' before it.
        x
        /^$/ {
                i\
apple
                g
        }
        ## Go back to pattern space to print at the end of this script.
        x
}

$ sed -f script.sed infile

apple
foofoo
foobaz
foobez

编辑:使用单行sed命令添加解决方案。

我不知道如何在一行中使用'i'命令,但下一个是相似的,它可以工作。

$ sed '/foo/ { x ; /^$/ { g ; s/^/apple\n/ ; x }; x }' infile
apple
foofoo
foobaz
foobez