I'm trying to replace some values from a string into another text, I've made a simplier example with numbers to be more comprehensive. Admitting I've generated a sequence from 1 to 100, I want to replace every numbers divisible by 3 or 5 and replace it by some texts for each case.
'''
#!/bin/bash
# generate a sequence and save it into a file
suite=$(seq -w 1 100)
echo $suite > suite.txt
# printing every multiple of 3 and 5
var3="$(awk -F' ' '{for(i=1;i<=NF;i )if(!($i%3))print $i}' suite.txt)"
var5="$(awk -F' ' '{for(i=1;i<=NF;i )if(!($i%5))print $i}' suite.txt)"
# replacing multiple of 3 and 5 by some text
sed -i 's/$var3/foo/g' suite.txt
sed -i 's/$var5/bar/g' suite.txt
'''
expected result : 001 002 foo 004 bar foo 007 008 foo bar etc.
My sed command doesn't work at all, I'm doing something wrong... Do you have any advise please ?
Thanks for your help Best regards
Golgoth
CodePudding user response:
Look what you are putting in var3
:
seq -w 1 100 | awk -F' ' '{for(i=1;i<=NF;i )if(!($i%3))print $i}'
# or with one field in each line
seq -w 1 100 | awk '$1%3==0 {print $i}'
This is a long string with numbers that you want to replace. When you want to use awk
for constructing a sed
condition, you need something like seq -w 1 100 | sed -r 's/^(003|006|009|012)$/foo/'
.
Constructing this line is possible with
var3=$(seq -w 1 100 | awk '$1%3==0 {total=total delim $1; delim="|"} END {print total}')
seq -w 1 100 | sed -r "s/^($var3)$/foo/g"
You don't need the sed
script
seq -w 1 100 | awk '{if ($1%3==0) print "foo"; else print $1}'
CodePudding user response:
While we could dynamically generate a series of sed
scripts to perform the replacements, one GNU awk
idea that may be a bit more straightforward:
awk -v replace="3:foo,5:bar" ' # <fieldno:replacement> pairs
BEGIN { n=split(replace,arr1,",") # split our fieldno:replacement pairs into the pairs[] array
for (i=1;i<=n;i ) {
split(arr1[i],arr2,":")
pairs[arr2[1]]=arr2[2] # index=fieldno, value=replacement
}
}
{ PROCINFO["sorted_in"]="@ind_num_asc" # apply replacements in fieldno (ascending) order
for (i in pairs)
for (j=i 0;j<=NF;j =i)
$j=pairs[i] # replace field #j with current pairs[i] value
}
1 # print current line
' suite.txt
This generates:
001 002 foo 004 bar foo 007 008 foo bar 011 foo 013 014 bar 016 017 foo 019 bar foo 022 023 foo bar 026 foo 028 029 bar 031 032 foo 034 bar foo 037 038 foo bar 041 foo 043 044 bar 046 047 foo 049 bar foo 052 053 foo bar 056 foo 058 059 bar 061 062 foo 064 bar foo 067 068 foo bar 071 foo 073 074 bar 076 077 foo 079 bar foo 082 083 foo bar 086 foo 088 089 bar 091 092 foo 094 bar foo 097 098 foo bar
NOTES:
- requires
GNU awk
forPROCINFO["sorted_in"]
support - for input fields that match multiple replacement criteria (eg, field #15), we apply all criteria to the field with the net result being that the highest numbered
pairs[]
index (5
in this case) is the final replacement for the field (eg, field #15 replaced withpairs[5]=bar
)