Ask Ubuntu is a question and answer site for Ubuntu users and developers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I tried the following command in my script:

find=grep "$jasper" | awk -F"reports/" '{print $2}'

Example output:


I want to change this output to something else, e.g. charts. For that, I tried:

sed -i /"$find"/charts

sed is causing me problems, it needs an input file but I don't have one. Is there a way to pipe the output from grep and awk to sed?

share|improve this question
(editing note) use two spaces instead of <br> for a line break, indent a string with four spaces and a newline before it to show it as code. – Lekensteyn Mar 15 '11 at 12:36
The use of grep, awk AND sed here makes it sound like you're doing this backwards (and grep | awk is pointless). It can probably be done with a single awk or sed. If you show some sample data and wanted output we might help you with that. – geirha Mar 15 '11 at 14:24
@geirha , thanks have a look my solution , any comment is acceptable ....thanks again – moata_u Mar 15 '11 at 17:02
up vote 1 down vote accepted

-i can only be used with sed if you're passing a file, it means "inline replace". Without this, the output of sed would be written to stdout (usually the console output). With -i, it does an inline replacement, that is, doing replacements in the file itself.

The next code reads the contents of into the variable $input (line 1) and finds the string to be replaced (line 2).
On the third line, it outputs the input string and pipes it through sed for replacement. sed outputs the string to stdout which will be caught by $( and ), and therefore be stored in $input.

read input <
find=$(grep "$jasper" | awk -F"reports/" '{print $2}')
input=$(echo "$input" | sed "s/$find/charts/")

If you want to apply the changes immediately to the file:

find=$(grep "$jasper" | awk -F"reports/" '{print $2}')
sed "s/$find/charts/" -i

From man sed:

          Attempt   to   match  regexp  against  the  pattern  space.   If
          successful, replace that portion matched with replacement.   The
          replacement may contain the special character & to refer to that
          portion of the pattern space  which  matched,  and  the  special
          escapes  \1  through  \9  to refer to the corresponding matching
          sub-expressions in the regexp.
share|improve this answer
thanks your answer was perfect ! – moata_u Mar 15 '11 at 13:31
but file will not changed ! – moata_u Mar 15 '11 at 13:46
I thought you wanted to store the output in a string. Added code for inline replacement. – Lekensteyn Mar 15 '11 at 13:55
first of all your answer was helpful , but i want replace it in file as well. – moata_u Mar 15 '11 at 14:07
@moata_u: like I said, I've added the code for that in the answer. It looks like sed "s/$find/charts/" -i Note that only one replacement per line is made. – Lekensteyn Mar 15 '11 at 14:10

You can always provide a pseudo-file with the < <(command) process substitution syntax:

sed -e "/$find/charts" < <(grep "$jasper" | awk -F"reports/" '{print $2}')
share|improve this answer
i tried : sed -i "/"$edit"/c charts" < <(edit=grep "$jasper" | awk -F"reports/" '{print $2}') seems not working !! – moata_u Mar 15 '11 at 9:40
Sorry, fixed - You shouldn't assign the result to a variable. – l0b0 Mar 15 '11 at 10:08
Thanks l0b0.... – moata_u Mar 16 '11 at 5:17
Minus for linking to a page that gives partly wrong information and exercises bad practice. It's best to avoid the advanced bash scripting guide unless you know how to filter out the junk. gives a correct and more complete explanation of process substitution. Also, grep|awk is silly; let awk do the "greping". – geirha Mar 20 '11 at 22:04
jasper=( maps charts widgets )
jasper1=( Maps Charts Widgets )

jasper_path=`find . -type f -name ''`

for (( i=0;i<$count;i++ )); do
sed -i "/${jasper[i]}.base/c com.jaspersoft.jasperreports.fusion.${jasper[i]}.base.swf.url=https://$host/webcare/reports/${jasper1[i]}" $jasper_path

other solution ()
find=$(grep "maps.base" | awk -F"reports/" '{print $2}';sed "s/$find/$host/" > tmp.txt.txt && mv tmp.txt

what am trying to do is the following :
1.find all files in directory that have name include 3 lines as you see from previous code ,three lines same only different word"maps,charts,widgets" )

2.point to each line individually and change host ip address for 3 three lines , with take concern of keeping "maps,charts,widgets" in the middle and "Maps,Charts,Widgets" at the end and as you see the 3 words at the end start with capital ...

share|improve this answer
Well there you go, one sed, that's much better :). You could do it all in one line, using find and GNU sed: find . -type f -name -exec sed -r -i "s#^([^=]*\.)(maps|charts|widgets)(\.base\.swf\.url).*#\1\2\3=https://$host/webc‌​are/reports/\u\2#" {} + – geirha Mar 15 '11 at 18:00
:)...wonderful...that work 100% perfectly in ubuntu , i will make some changes your code try not use -i option other wise script will not work in solaris... – moata_u Mar 15 '11 at 18:27
i isn't the only part that isn't portable there. Solaris's sed also don't know extended regular expressions, which was used there (-r enables ERE). A portable solution is harder. Your approach in the answer is closer to a portable solution. – geirha Mar 15 '11 at 20:45

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.