From owner-freebsd-questions Wed Mar 12 8:51:58 2003 Delivered-To: freebsd-questions@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id E282B37B401 for ; Wed, 12 Mar 2003 08:51:54 -0800 (PST) Received: from mailsrv.otenet.gr (mailsrv.otenet.gr [195.170.0.5]) by mx1.FreeBSD.org (Postfix) with ESMTP id 1046F43F85 for ; Wed, 12 Mar 2003 08:51:53 -0800 (PST) (envelope-from keramida@ceid.upatras.gr) Received: from gothmog.gr (patr530-b239.otenet.gr [212.205.244.247]) by mailsrv.otenet.gr (8.12.8/8.12.8) with ESMTP id h2CGpmp7006559; Wed, 12 Mar 2003 18:51:50 +0200 (EET) Received: from gothmog.gr (gothmog [127.0.0.1]) by gothmog.gr (8.12.8/8.12.8) with ESMTP id h2CGpmrC006313; Wed, 12 Mar 2003 18:51:48 +0200 (EET) (envelope-from keramida@ceid.upatras.gr) Received: (from giorgos@localhost) by gothmog.gr (8.12.8/8.12.8/Submit) id h2CGcNQ8005380; Wed, 12 Mar 2003 18:38:23 +0200 (EET) (envelope-from keramida@ceid.upatras.gr) Date: Wed, 12 Mar 2003 18:38:23 +0200 From: Giorgos Keramidas To: Kok Kok Cc: freebsd-questions@FreeBSD.ORG Subject: Re: sed to replace the words Message-ID: <20030312163823.GC5097@gothmog.gr> References: <20030312061655.26510.qmail@web13305.mail.yahoo.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20030312061655.26510.qmail@web13305.mail.yahoo.com> Sender: owner-freebsd-questions@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG On 2003-03-12 01:16, Kok Kok wrote: > Hi all > > I have question how to replace words using sed > > ./script 61.100 192.168 > > The script is > > #!/bin/sh > sed -e 's/$2/$1/g' file > newfile > > The problem is 192.168 can't replace 61.100 in the > newfile . The sed utility won't see the value of $1 or $2 in this script, since you used simple quotes, which inhibit shell variable substitution. . The order of $1 and $2 is reversed. . Even if you swap $1 and $2 and change ' to ", the results can be weird for patterns that include the '.' character since it's a special sed character that matches *any* character. You need to escape it with a backslash (\) before testing it on real files. . The name of 'newfile' is hardwired, which means you can't run the script to substitute "$1" to "$2" on many files. One example of doing this with a relatively easy way would be: 1 #!/bin/sh 2 3 if [ $# -lt 2 ]; then 4 echo "usage: `basename $0` p-before p-after [file ...]" >&2 5 exit 1 6 fi 7 8 p_before="$1" 9 p_after="$2" 10 11 shift && shift 12 for fname in "$@" ;do 13 echo "Filtering ${fname} ..." 14 15 # Escape '.' and '|' in $p_before to avoid matching too many 16 # things. 17 p_before=$(echo "${p_before}" | sed -e 's|\.|\\.|g' -e 's,|,\\|,g') 18 19 # Filter, using a temp file. 20 tmpfile=$(mktemp ${TMPDIR:-/tmp}/sedXXXX 2>&1 || echo "") 21 if [ X"${tmpfile}" = X"" ]; then 22 echo "Can't create temp file." >&2 23 exit 1 24 fi 25 sed -e "s|${p_before}|${p_after}|g" "${fname}" > "${tmpfile}" 26 cat "${tmpfile}" > "${fname}" 27 /bin/rm -f "${tmpfile}" 28 done This script when run on a sample test I did seems to do what you asked, avoiding unnecessary matches: giorgos@gothmog[18:26]/home/giorgos$ cat koko This is a test line that should remain intact, despite having 150\.140 in it. The lines that include 150.140 should match and be changed. All other lines stay the same, since i.e. 150 140 doesn't match. giorgos@gothmog[18:26]/home/giorgos$ sh lala.sh 150.140 192.168 koko Filtering koko ... giorgos@gothmog[18:26]/home/giorgos$ cat koko This is a test line that should remain intact, despite having 150\.140 in it. The lines that include 192.168 should match and be changed. All other lines stay the same, since i.e. 150 140 doesn't match. There are quite a few tricks in that script which you probably don't need, but it does what you asked. Some sort of error checking for sed failures should be added, and you should probably check that it makes sense to overwrite the original file after sed is done, but well... that's another thing. - Giorgos To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-questions" in the body of the message