Reputation: 115
I have two files. Both files are a TXT.
File one contains strings, one per line.
File two contains some text.
File two looks like this:
title:
VALUE:
display_name: VALUE
resource:
material: material
generate: false
model_path: model/VALUE
title:
VALUE:
display_name: VALUE
resource:
material: material
generate: false
model_path: model/VALUE
File one like this:
einundzwanzig
dreiundzwanzig
vierundzwanzig
fuenfundzwanzig
My intention is, that VALUE gets replaced with the string in line one, for three times. Then for the next three VALUEs the second string. And so on. I tried to get it done by using bash, but it doesn't work out.
So I tried following script:
count=1
# filetwo.txt is your file
cat test.xml | tr "\n" "\t" > test2.xml
while read line
do
echo $count
echo $line
sed -i " s_value[^<]*value_value$linevalue_${count}; " fileone.txt
((count++))
done < filetwo.txt
cat test2.xml | tr "\t" "\n" >fileoutput.txt
But it does not want to work :(
Upvotes: 0
Views: 63
Reputation: 58578
This might work for you (GNU sed):
sed -Ee '1{x;s/^/cat file1/e;x} # copy file1 to hold space
:a;/title:/{ # when line contains title:
:b;n;/title:/{x;s/^[^\n]*\n//;x;ba} # end of stanza reduce file1
/VALUE/{G;s/VALUE([^\n]*)\n(\S+).*/\2\1/} # replace VALUE
bb}' file2 # repeat
On line one, copy the contents of file1 into the hold space.
If a line contains title:
print that line and fetch the next.
If that line contains title
, remove the first line of file1 in the hold space and repeat from loop holder :a
.
Otherwise, if the current line contains VALUE
, append the hold space to the current line and replace VALUE
by the first line in the hold space.
Repeat from loop holder :b
.
Alternative, just replace 3 VALUE
fields in file2 for each line in file1:
sed -E '1{x;s/^/sed "p;p" file1/e;x}
:a;/VALUE/{G;s/VALUE([^\n]*)\n(\S+).*/\2\1/;x;s/[^\n]*\n//;x;ba}' file2
Upvotes: 2
Reputation: 35556
Assumptions:
VALUE
VALUE
does not show up in a longer string (eg, DEVALUE
)VALUE
strings is less than (or equal) to three times the number of replacement strings (ie, we won't run out of replacement strings)Input files:
$ cat value.template
title:
VALUE:
display_name: VALUE
resource:
material: material
generate: false
model_path: model/VALUE
title:
VALUE:
display_name: VALUE
resource:
material: material
generate: false
model_path: model/VALUE
title:
VALUE:
display_name: VALUE
model_path: model/VALUE
title:
VALUE:
display_name: VALUE
model_path: model/VALUE
$ cat value.dat
einundzwanzig
dreiundzwanzig
vierundzwanzig
fuenfundzwanzig
One awk
solution:
awk '
BEGIN { i=1 } # initialize our array counter
# process first file (NR==FNR)
NR==FNR { v[i++]=v[i++]=v[i++]=$1 ; next } # save the replacement string in next 3 array slots
# process second file
FNR==1 { i=1 } # for first line of 2nd file, reset our array counter
/VALUE/ { while ( sub("VALUE",v[i]) ) { i++ } } # if line includes "VALUE" string then replace each occurrence with next array element referenced by "i"; increment i for next sub()/match
{ print } # print current line
' value.dat value.template
A different awk
solution that stores the replacement strings just once in the v[]
array:
awk '
BEGIN { i=0 } # initialize array counter
NR==FNR { v[i++]=$1 ; next } # save the replacement string in next array slot
FNR==1 { i=1 } # for first line of 2nd file, reset our array counter
/VALUE/ { while ( sub("VALUE",v[int((i-1)/3)]) ) { i++ } } # for every 3 instances of "VALUE" replace with the same entry from the v[] array; increment i after each sub()/match
{ print } # print current line
' value.dat value.template
NOTE: Remove comments to declutter code
Both of the above generate:
title:
einundzwanzig:
display_name: einundzwanzig
resource:
material: material
generate: false
model_path: model/einundzwanzig
title:
dreiundzwanzig:
display_name: dreiundzwanzig
resource:
material: material
generate: false
model_path: model/dreiundzwanzig
title:
vierundzwanzig:
display_name: vierundzwanzig
model_path: model/vierundzwanzig
title:
fuenfundzwanzig:
display_name: fuenfundzwanzig
model_path: model/fuenfundzwanzig
Upvotes: 2