I have the following string:
"Last updated Unknown </DIV> </DIV></DIV></TD></TR></TABLE></FORM></DIV></BODY></HTML>"
and I am trying a simple example to replace HTML with test
but if I try this example I get a unexpected results:
echo "Last updated Unknown</DIV></DIV></DIV></TD></TR></TABLE></FORM></DIV></BODY></HTML>" | tr "HTML" "test"
Result:
tast updated Unknown </DIV> </DIV></DIV></eD></ eR></eABtE></FORs></DIV></BODY></test>
tr is used to translate or delete characters. Try sed instead:
sed 's/HTML/test/g'
tr "HTML" "test" replaces H by t, T by e, M by s and L by t.
You could use sed instead.
$ echo "Last updated Unknown </DIV> </DIV></DIV></TD></TR></TABLE></FORM></DIV></BODY></HTML>" | sed 's/HTML/test/g'
Last updated Unknown </DIV> </DIV></DIV></TD></TR></TABLE></FORM></DIV></BODY></test>
Related
I'm using hxselect to process a HTML file in bash.
In this file there are multiple divs defined with the '.row' class.
In bash I want to extract these 'rows' into an array. (The divs are multilined so simply reading it line-by-line is not suitable.)
Is it possible to achieve this? (With basic tools, awk, grep, etc.)
After assigning rows to an array, I want to further process it:
for row in ROWS_EXTRACTED; do
PROCESS1($row)
PROCESS2($row)
done
Thank you!
One possibility would be to put the content of the tags in an array with each item enclosed in quotes. For example:
# Create array with " " as separator
array=`cat file.html | hxselect -i -c -s '" "' 'div.row'`
# Add " to the beginning of the string and remove the last
array='"'${array%'"'}
Then, processing in a for loop
for index in ${!array[*]}; do printf " %s\n\n" "${array[$index]}"; done
If the tags contain the quote character, another solution would be to place a separator character not found in the tags content (§ in my example) :
array=`cat file.html | hxselect -i -c -s '§' 'div.row'`
Then do a treatment with awk :
# Keep only the separators to count them with ${#res}
res="${array//[^§]}"
for (( i=1; i<=${#res}; i++ ))
do
echo $array2 | awk -v i="$i" -F § '{print $i}'
echo "----------------------------------------"
done
The following instructs hxselect to separate matches with a tab, deletes all newlines, and then translates the tab separators to newlines. This enables you to iterate over the divs as lines with read:
#!/bin/bash
divs=$(hxselect -s '\t' .row < "$1" | tr -d '\n' | tr '\t' '\n')
while read -r div; do
echo "$div"
done <<< "$divs"
Given the following test input:
<div class="container">
<div class="row">
herp
derp
</div>
<div class="row">
derp
herp
</div>
</div>
Result:
$ ./test.sh test.html
<div class="row"> herp derp </div>
<div class="row"> derp herp </div>
I would like to replace a digit between two HTML tags, but still have a problem and command sed does not work:
string to replace - <p key=SaveFile>0</p>
new string - <p key=SaveFile>1</p>
Code:
sed -i 's/\<p key\=SaveFile\>0\<\/p\>/<p key=SaveFile>1<\/p>/' newfile.xml
It's easier if you use another delimiter for s like | or #:
echo "<p key=SaveFile>0</p>" | sed 's|<p key=SaveFile>0</p>|<p key=SaveFile>1</p>|'
If you want to replace any number between the two tags simply use [0-9]\+ or [0-9]+ (with option -r):
echo "<p key=SaveFile>1234</p>" | sed 's|<p key=SaveFile>[0-9]\+</p>|<p key=SaveFile>1</p>|'
Output:
<p key=SaveFile>1</p>
Application can be
sed -i 's|<p key=SaveFile>0</p>|<p key=SaveFile>1</p>|' newfile.xml
Or with g:
sed -i 's|<p key=SaveFile>0</p>|<p key=SaveFile>1</p>|g' newfile.xml
I have a string:
(string1) "String2_With_More_Parts"
and need the (string1) deleted from my variable.
You can use sed:
echo '(string1) "String2_With_More_Parts"' | sed -e s/\(string1\)\ //
This gives the output:
"String2_With_More_Parts"
This may be a bit complex, but here it goes:
Assuming I have an XML that looks as follows:
<a>
<b>000</b>
<c>111</c>
<b>222</b>
<d>333</d>
<c>444</c>
</a>
How can I, using sed on a mac, get a resulting an XML that looks as follows:
<a>
<b>111 000</b>
<b>222</b>
<d>333</d>
<c>444</c>
</a>
Basically:
Matching 2 consecutive lines that are of the form <b>...</b> followed by </c>...</c>
Taking the value between <c>...</c> and placing it (plus a space character) right after <b> on the line before it
Removing the second line <c>...</c>
Thank you.
If sed is too much for this, please advise anything else as long as I can run it from a mac shell.
Not the most beautiful solution but it seams to work :-)
$ tr '\n' # < input | sed 's#<b>\([0-9]\+\)</b>#<c>\([0-9]\+\)</c>#<b>\2 \1</b#g' | tr # '\n'
output:
<a>
<b>111 000</b
<b>222</b>
<d>333</d>
<c>444</c>
</a>
or a bit more general:
$ tr '\n' # < f1 | sed 's#<b>\([^<]*\)</b>#<c>\([^<]*\)</c>#<b>\2 \1</b#' | tr # '\n'
using [^<] to match anything between brackets
Ruby would support multi-line patterns:
ruby -e 'print gets(nil).sub(/<b>([^\n]*)<\/b>\n<c>([^\n]*)<\/c>/m,"<b>\\2 \\1</b>")' file.txt
What would be the sed command for mac shell scripting that would replace all iterations of string "fox" with the entire string content of myFile.txt.
myFile.txt would be html content with line breaks and all kinds of characters. An example would be
</div>
</div>
<br>
<div id="container2">
<div class="question" onclick="javascript:show('answer2')";>
Thanks!
EDIT 1
This is my actual code:
sed -i.bkp '/Q/{
s/Q//g
r /Users/ericbrotto/Desktop/question.txt
}' $file
When I run it I get:
sed in place editing only works for regular files.
And in my files the Q is replaced by a ton of chinese characters (!). Bizarre!
You can use the r command. When you find a 'fox' in the input...
/fox/{
...replace it for nothing...
s/fox//g
...and read the input file:
r f.html
}
If you have a file such as:
$ cat file.txt
the
quick
brown
fox
jumps
over
the lazy dog
fox dog
the result is:
$ sed '/fox/{
s/fox//g
r f.html
}' file.txt
the
quick
brown
</div>
</div>
<br>
<div id="container2">
<div class="question" onclick="javascript:show('answer2')";>
jumps
over
the lazy dog
dog
</div>
</div>
<br>
<div id="container2">
<div class="question" onclick="javascript:show('answer2')";>
EDIT: to alter the file being processed, just pass the -i flag to sed:
sed -i '/fox/{
s/fox//g
r f.html
}' file.txt
Some sed versions (such as my own one) require you to pass an extension to the -i flag, which will be the extension of a backup file with the old content of the file:
sed -i.bkp '/fox/{
s/fox//g
r f.html
}' file.txt
And here is the same thing as a one liner, which is also compatible with Makefile
sed -i -e '/fox/{r f.html' -e 'd}'
Ultimately what I went with which is a lot simpler than a lot of solutions I found online:
str=xxxx
sed -e "/$str/r FileB" -e "/$str/d" FileA
Supports templating like so:
str=xxxx
sed -e "/$str/r $fileToInsert" -e "/$str/d" $fileToModify
Another method (minor variation to other solutions):
If your filenames are also variable ( e.g. $file is f.html and the file you are updating is $targetfile):
sed -e "/fox/ {" -e "r $file" -e "d" -e "}" -i "$targetFile"