1

I tried the following command in my script:

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

Example output:

maps

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?

3
  • (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, 2011 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, 2011 at 14:24
  • @geirha , thanks have a look my solution , any comment is acceptable ....thanks again
    – moata_u
    Mar 15, 2011 at 17:02

3 Answers 3

1

-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 jasperreports.properties 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 < jasperreports.properties
find=$(grep "$jasper" jasperreports.properties | 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" jasperreports.properties | awk -F"reports/" '{print $2}')
sed "s/$find/charts/" -i jasperreports.properties

From man sed:

   s/regexp/replacement/
          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.
4
  • but jasperreports.properties file will not changed !
    – moata_u
    Mar 15, 2011 at 13:46
  • I thought you wanted to store the output in a string. Added code for inline replacement.
    – Lekensteyn
    Mar 15, 2011 at 13:55
  • first of all your answer was helpful , but i want replace it in file jasperreports.properties as well.
    – moata_u
    Mar 15, 2011 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 jasperreports.properties. Note that only one replacement per line is made.
    – Lekensteyn
    Mar 15, 2011 at 14:10
1

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

sed -e "/$find/charts" < <(grep "$jasper" jasperreports.properties | awk -F"reports/" '{print $2}')
3
  • i tried : sed -i "/"$edit"/c charts" < <(edit=grep "$jasper" jasperreports.properties | awk -F"reports/" '{print $2}') seems not working !!
    – moata_u
    Mar 15, 2011 at 9:40
  • Sorry, fixed - You shouldn't assign the result to a variable.
    – l0b0
    Mar 15, 2011 at 10:08
  • 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. mywiki.wooledge.org/ProcessSubstitution gives a correct and more complete explanation of process substitution. Also, grep|awk is silly; let awk do the "greping".
    – geirha
    Mar 20, 2011 at 22:04
0
jasper=( maps charts widgets )
jasper1=( Maps Charts Widgets )


count=${#jasper[*]}            
jasper_path=`find . -type f -name 'jasperreports.properties'`

count=${#jasper[*]}
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
done

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

what am trying to do is the following :
1.find all files in directory that have name jasperreport.properties(which 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 ...

3
  • 1
    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 jasperreport.properties -exec sed -r -i "s#^([^=]*\.)(maps|charts|widgets)(\.base\.swf\.url).*#\1\2\3=https://$host/webcare/reports/\u\2#" {} +
    – geirha
    Mar 15, 2011 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, 2011 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, 2011 at 20:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .