Reputation: 325
I want to run a program while scanning a range of parameters and I need to replace a word in a specific location without matching any pattern
for example my input file contains the following lines:
...
coords xyz
O 0.0 0.0 0.0
H 1.0 1.0 0.0
H 1.0 -1.0 0.0
...
I want substitute the 3rd word in the 66th line (in this example "-1.0") with a different ($i) value in each iteration
I know I can maintain a original_input file, do a pattern search and output it to a Input file each time :
sed "6s/-1.0/$i/" original_input > Input
but I'm looking for a in-place substitute while the match pattern is continuously changing
Upvotes: 0
Views: 86
Reputation: 325
For my use I wrapped yunnosch's answer within a bash script:
#!/bin/bash
# substitute a word in a predefined location disregarding its value
# applied with 4 arguments: ( number of word inside a line, number of line, new value and input text)
# add a 5th argument "-i" to do a in place substitution
echo substituting the \#$1 word in the \#$2 line with $3
declare -i a=$1
let a-=1
sed -E $5 " $2s/(\s*(\S+\s+){$a})\S+(\s+|$)/\1$3\3/;" $4
Upvotes: 0
Reputation: 26703
I am interpreting
"in-place substitution" as
"substitute in a place which is given by line number and word number"
and that "match pattern" refers in sample case to "-1.0", which you do not want occurring hard-coded in the implementation.
I hope the requirement "without matching any pattern" only refers to the actual replacing, allowing more generic pattern matching elsewhere.
My proposed implementation to solve this:
bash-3.1$ sed -E "4s/(\s*(\S+\s+){2})\S+(\s+|$)/\1$i\3/;" input.txt
Output for given sample input (without "..."), for $i==5:
coords xyz
O 0.0 0.0 0.0
H 1.0 1.0 0.0
H 1.0 5 0.0
In the implementation
"4" is the line number,
"2" is the word number (start counting at 0).
In the output "5" is the replacement.
Getting the line number right was already solved by you.
I did the word number by requiring in the regex the right number {n}
of preceeding "nonwhitespace + whitespace", i.e. \S+\s+
.
Upvotes: 1