Asked  6 Months ago    Answers:  5   Viewed   26 times

I am using the below code for replacing a string inside a shell script.

echo $LINE | sed -e 's/12345678/"$replace"/g'

but it's getting replaced with $replace instead of the value of that variable.

Could anybody tell what went wrong?

 Answers

84

If you want to interpret $replace, you should not use single quotes since they prevent variable substitution.

Try:

echo $LINE | sed -e "s/12345678/${replace}/g"

Transcript:

pax> export replace=987654321
pax> echo X123456789X | sed "s/123456789/${replace}/"
X987654321X
pax> _

Just be careful to ensure that ${replace} doesn't have any characters of significance to sed (like / for instance) since it will cause confusion unless escaped. But if, as you say, you're replacing one number with another, that shouldn't be a problem.

Tuesday, June 1, 2021
 
OMGKurtNilsen
answered 6 Months ago
38

To replace the first occurrence of a pattern with a given string, use ${parameter/pattern/string}:

#!/bin/bash
firstString="I love Suzi and Marry"
secondString="Sara"
echo "${firstString/Suzi/$secondString}"    
# prints 'I love Sara and Marry'

To replace all occurrences, use ${parameter//pattern/string}:

message='The secret code is 12345'
echo "${message//[0-9]/X}"           
# prints 'The secret code is XXXXX'

(This is documented in the Bash Reference Manual, §3.5.3 "Shell Parameter Expansion".)

Note that this feature is not specified by POSIX — it's a Bash extension — so not all Unix shells implement it. For the relevant POSIX documentation, see The Open Group Technical Standard Base Specifications, Issue 7, the Shell & Utilities volume, §2.6.2 "Parameter Expansion".

Tuesday, June 1, 2021
 
Giovanni
answered 6 Months ago
44
awk 'BEGIN {
 lvl[0] = "warning"
 lvl[1] = "error"
 lvl[2] = "critical"
 }
NR == FNR {
  evt[$1] = $2; next
  } 
{
  print $2, evt[$2], lvl[$3]
  }' dictionary infile
Tuesday, August 3, 2021
 
showstealer
answered 4 Months ago
65

Here is a variation on ghostdog74's answer that does not require the number to be anchored at the end of the string. This is accomplished using match instead of relying on the number to be in a particular position.

This will replace the first number with its value minus one:

$ echo "eh oh    37      aaa     22    bb" | awk '{n = substr($0, match($0, /[0-9]+/), RLENGTH) - 1; sub(/[0-9]+/, n); print }'
eh oh    36      aaa     22    bb

Using gsub there instead of sub would replace both the "37" and the "22" with "36". If there's only one number on the line, it doesn't matter which you use. By doing it this way, though, it will handle numbers with trailing whitespace plus other non-numeric characters that may be there (after some whitespace).

If you have gawk, you can use gensub like this to pick out an arbitrary number within the string (just set the value of which):

$ echo "eh oh    37      aaa     22    bb    19" |
    awk -v which=2 'BEGIN { regex = "([0-9]+)\>[^0-9]*";
        for (i = 1; i < which; i++) {regex = regex"([0-9]+)\>[^0-9]*"}}
        { match($0, regex, a);
        n = a[which] - 1;                    # do the math
        print gensub(/[0-9]+/, n, which) }'
eh oh    37      aaa     21    bb    19

The second (which=2) number went from 22 to 21. And the embedded spaces are preserved.

It's broken out on multiple lines to make it easier to read, but it's copy/pastable.

Tuesday, October 19, 2021
 
James Kovacs
answered 1 Month ago
11

Install the Find And Replace Text command line utility and then you can simply enter

fart *.txt E:Test E:TestTemp
Tuesday, November 9, 2021
 
Bart Kiers
answered 3 Weeks ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share