Reputation: 26968
Add a apple string when i find the first pattern of foo.
Input data:
foofoo
foobaz
foobez
Results:
apple
foofoo
foobaz
foobez
is that possible to do it using bash/sed ?
thanks
Upvotes: 0
Views: 462
Reputation: 36262
Using '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
Edit: Add a solution using a one-line sed command.
I don't know how to use the 'i\' command in one line, but next one is similar and it works.
$ sed '/foo/ { x ; /^$/ { g ; s/^/apple\n/ ; x }; x }' infile
apple
foofoo
foobaz
foobez
Upvotes: 1
Reputation: 27844
Not bash/sed but perl, which is a speciality of mine.
perl -pE 'say "apple" if /^foo/ and not $seen_foo++'
For each line, say "apple" if the line starts with "foo" and we have not seen one such line before, then print the line.
Upvotes: 2
Reputation: 21
Pure Bash:
nl=$'\n'
str='foofoo
foobaz
foobez
'
echo "${str/foo/apple${nl}foo}"
Upvotes: 1
Reputation: 17614
I assume, that list is a file(?). So using just Bash
(just for fun, perl is so much more powerful in its expressiveness) I'd do it like this:
#!/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"
use it like this:
$ that_script apples file
Inspired by my answer in a similar question
NOTE: this just looks if the string starts with foo
. Place your own pattern, by changing the line below, to whatever suits you:
if [[ $REPLY =~ ^foo ]]; then
Upvotes: 1
Reputation: 6001
#!/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
Translated the perl answer to bash If you save the above as /tmp/x and your input as /tmp/x1 you would run it like this
bash /tmp/x < /tmp/x1
Upvotes: 1