user7649922
user7649922

Reputation: 623

Python or Shell assistance: How to search for a word and replace only the value next to it

I have a text file (list.txt) with the following format:

Apple 1
Banana 5.0
orange_1 0.5

The list can go on for many lines. I would like to ultimately search for the word "Apple" and only replace the value next to it. I know how to use a "sed" command that can search and replace a word but I don't know how I can search for a word and replace only the value next to it?

the sed command I use in my script is a s follows:

sed "s/Apple/$1/g" list.txt > newlist.txt 

where $1 is defined in a run script and could be anything (e.g. grape). Again this would switch the word Apple and not the value next to it. I would like to be able to perform this action either by using a SHELL or Python command. Any help would be fantastic!

Upvotes: 1

Views: 357

Answers (2)

Andrey
Andrey

Reputation: 2591

Assuming that each line starts with the key and the value is the rest of the line after a space, you can use the following sed command to replace only the value:

sed "s/\(^Apple \)\(.*$\)/\1$1/"

Please note that this might be a fragile/insecure solution depending on the replacement value, e.g. if $1 contains /, it can be used for a command insertion like /;d;s//.

A more robust solution with awk:

awk -v new="$1" '{print ($1 == "Apple") ? ($1 " " new) : $0}'

UPD. Both commands can work with files either directly or via standard streams:

sed ... file.txt > new.txt
cat file.txt | sed ... | cat > new.txt

(do not use cat like this, it's here to show piped input/output). Additionally, some versions of sed have option -i to change file in place:

sed -i ... file.txt

Upvotes: 0

Menglong Li
Menglong Li

Reputation: 2255

Here I show positive lookback way as @ryugie said:

content = '''Apple 1
Banana 5.0
orange_1 0.5'''


def my_replace(content, fruit, value):
    import re
    return re.sub(r'(?<=' + fruit + ' )([\d\.]+)', str(value), content)


print my_replace(content, 'Apple', 4.0)

print my_replace(content, 'Banana', 1.5)

And we can get:

Apple 4.0
Banana 5.0
orange_1 0.5

Apple 1
Banana 1.5
orange_1 0.5

Upvotes: 2

Related Questions