marc wrote:
Would you mind explaing what that sentence does? I mean, step by step ;)
Sure, I'll explain everything :)
To take it from the beginning, you might be familiar with the basic logic operators '&&' and '||'. The following is used to run command_1, and then command_2 - if and only if command_1 is successful.
command_1 && command_2
This is used to run command_2 only if command_1 is
not successful:
command_1 || command_2
In the original script, I wrote something like this:
( command_1 && command_2 && command_3 ) || ( command_4; command_5)
The parentheses are used to glue together several commands into one block of code. If one of the commands inside the first parentheses fails (that is,
command_1,
command_2 or
command_3), it counts as if the whole block of commands fails - and then the '||' operator makes sure the second block of code is executed instead (
command_4 and
command_5).
But when a block of commands consists of seven different commands, the script gets easier to manage if the commands are spread through different lines. You can do this by escaping the newlines ("\\<newline>" ), so that Bash will ignore them:
( command_1 \\
&& command_2 \\
&& command_3 ) \\
|| ( command_4; command_5)
But the forums added whitespace to the end of each line, here represented by red underscores:
( command_1 \\[color=#FF0000]_[/color]
&& command_2 \\[color=#FF0000]_[/color]
&& command_3 ) \\[color=#FF0000]_[/color]
|| ( command_4; command_5)
This means that Bash reads "\\<space><newline>" instead of "\\<newline>", which makes the interpreter ignore the whitespace instead of ignoring the newline. (I discovered this by using
gvimdiff to compare the old, working script I had on my harddrive with with a copy of the script I copy/pasted from the forums.)
I then used sed, a tool used for search-and-replace actions, to correct this. Using sed is quite simple:
sed 's/old/new/g' filename
The "s" stands for "substitute", the slash is a delimiter, and the "g" at the end means "global". Sed will then read the file
filename and substitute every occurrence of "old" in
filename with "new", and write the modified file to standard output.
In this case, I wanted to replace every occurence of '\\ ' with just '\\'. Since Sed itself interprets backslashes (so that you e.g. can replace all newlines by using '\\n', or all tabs with '\\t' ), the backslashes themselves have to be escaped. If we also escape the whitespace, the pattern '\\ ' becomes '\\\\\\ ', and '\\' becomes '\\\\'. We also want to save the output back to the original file by piping the output:
sed 's/\\\\\\ /\\\\/g' filename > filename
A more specific solution, and in many cases a better one, would be to replace '\\<space><newline>' with '\\<newline>':
sed 's/\\\\\\ \\n/\\\\\\n/g' filename > filename
If not given any input files,
sed will read standard input, so something like this should work equally well:
cat filename|sed 's/old/new/g' > filename
The 'g' at the end can also be replaced with a number:
sed 's/old/new/1' # Replace only 1. occurrence of "old"
sed 's/old/new/2' # Replace only 2. occurrence of "old"
Hope this helps :)