0

I have a bash script which has about 2000 lines of code and in this script on various lines the scripts writes some status messages to a log file i.e. LogFiles.txt,bills.txt I want to comment(search and replace the text) for all the lines writing the status messages in LogFiles.txt only

Sample script file:

echo "+++++++++++++++++++++">>bills.txt
echo "doing some stuff">>bills.txt
echo "starting
to execute some commands">>LogFiles.txt
echo "----------------------">>LogFiles.txt
ls 
cat someFile.txt| grep "search me"
echo "search results found">>LogFiles.txt
echo "----------------------">>LogFiles.txt
echo "+++++++++++++++++++++">>bills.txt
echo "doing some more stuff">>bills.txt
some other commands...
echo "finshing 
script
 execution">>LogFiles.txt
echo "----------------------">>LogFiles.txt

desired Output:

echo "+++++++++++++++++++++">>bills.txt
echo "doing some stuff">>bills.txt
/*echo "starting
to execute some commands">>LogFiles.txt*/
/*echo "----------------------">>LogFiles.txt*/
ls 
cat someFile.txt| grep "search me"
/*echo "search results found">>LogFiles.txt*/
/*echo "----------------------">>LogFiles.txt*/
echo "+++++++++++++++++++++">>bills.txt
echo "doing some more stuff">>bills.txt
some other commands...
/*echo "finshing 
script
 execution">>LogFiles.txt*/
/*echo "----------------------">>LogFiles.txt*/

uptill now i have used the following command but the results are not good:

sed -e 's/echo/\/\*echo/gI' -e 's/LogFiles.txt/LogFiles.txt\*\//gI' samplescript.sh

the results that this command produces:

/*echo "doing some stuff">>bills.txt
/*echo "starting
to execute some commands">>LogFiles.txt*/
/*echo "----------------------">>LogFiles.txt*/
ls
cat someFile.txt| grep "search me"
/*echo "search results found">>LogFiles.txt*/
/*echo "----------------------">>LogFiles.txt*/
some other commands...
/*echo "finshing
script
 execution">>LogFiles.txt*/
/*echo "----------------------">>LogFiles.txt*/

here the problem arises when the first part of the sed -e command replaces all the echo with /*echo which is a wrong approach since i do not need to comment echos for bills.txt.

Aserre
  • 4,916
  • 5
  • 33
  • 56
  • 2
    You do realise this is not the [correct syntax for multiline comments in bash](https://stackoverflow.com/questions/43158140/way-to-create-multiline-comments-in-bash) ? – Aserre May 29 '18 at 09:47
  • @Hammad Ahmed, why not do with a single `#` if lines are not continuous?? – RavinderSingh13 May 29 '18 at 09:49
  • BTW, using one `>>` per line is really, **really** inefficient -- it means you're re-opening the output file when you want to write a line to it, writing that one line, and then closing the file, only to re-open it again for the next command! Much more efficient to just open the output file *once*, and reuse the file descriptor; for example, `exec 3>LogFile.txt`, and then put `>&3` on every line whose output should be written to it. Or `exec >LogFile` to redirect all of stdout for the whole rest of the script, or create a block with `{` and `} >LogFile` to redirect only code in that block. – Charles Duffy May 29 '18 at 17:15

3 Answers3

1

Using : ' and ' syntax for multiline comments in bash, as pointed by @Aserre, with sed:

sed -r -e "/^echo/ {/>>/ bb; :a; N; />>/! ba; :b; />>LogFiles\.txt/I {s/^echo/: ' echo/; s/(>>.*)$/\1 '/}}" samplescript.sh

Also use -i to directly write on script file.


Sed command explanation:

/^echo/ {              # in a line that starts with 'echo'
  />>/ bb              # if also already contains '>>' jump forward to 'b' label
  :a                   # 'a' label to jump to
  N                    # read next line and add it to pattern space
  />>/! ba             # if pattern space not contains '>>' jump back to 'a' label
  :b                   # 'b' label to jump to
  />>LogFiles\.txt/I { # now if pattern space contains '>>LogFiles.txt' case insensitive
    s/^echo/: ' echo/  # add open comment before 'echo'
    s/(>>.*)$/\1 '/    # add close comment at the end of the line with '>>'
  }
}
Hazzard17
  • 633
  • 7
  • 14
  • also i was intrested if we could cater case sensitivity as well – Hammad Ahmed May 30 '18 at 06:20
  • Do you mean case sensitivity in log file name? Also how about white spaces? I have customized the answer based on your example, please provide every possible syntax modification of input file. Anyway you have simply to adjust regex to match all these cases. – Hazzard17 May 30 '18 at 07:25
  • yes i want to cater the cases eg. Collect and COLLECT are two same words i want to search Collect and all the occurence of collect should be commented in the script /I flag basically is used for ignoring case sensitivity where do i use it in this command – Hammad Ahmed May 30 '18 at 08:06
  • also if you could explain "{/>>/ bb; :a; N; />>/! ba; :b;" this part of the script as well :) – Hammad Ahmed May 30 '18 at 08:10
  • hey @Hazzard17 how can we ignore case sensitivity in {s/^echo/: ' echo/; s/(>>.*)$/\1 '/}} while replacing the strings! other than that every thing is fine – Hammad Ahmed May 30 '18 at 09:18
  • Please provide clarification and full example about what you want to archive. Based on your example input this fully works. – Hazzard17 May 30 '18 at 11:04
0

Following simple awk may help you here.

awk '/LogFiles.txt$/{$0="##"$0} 1'  Input_file

In case you want to store output into Input_file itself append > temp_file && mv temp_file Input_file in above code then.

Solution 2nd: Using sed with backup of actual Input_file.

sed -i.bak '/LogFiles.txt$/s/^/##/'  Input_file
RavinderSingh13
  • 130,504
  • 14
  • 57
  • 93
  • DOWN VOTER, please do let me know the reason for down voting on this?? – RavinderSingh13 May 29 '18 at 10:02
  • it is commenting lines containing /LogFiles.txt but is not commenting the start of the comment i.e. echo" i want echo to be commented over here as well – Hammad Ahmed May 29 '18 at 10:03
  • @HammadAhmed, what do you mean start of comment here?? Please elaborate more. – RavinderSingh13 May 29 '18 at 10:06
  • if u would have a look at the sample file the log message starts on the previous lines while the log message ends at LogFile.txt so the comment has to be started from echo while terminating at Logfiles.txt – Hammad Ahmed May 29 '18 at 10:16
  • @HammadAhmed, BINGO, that was my point. In shell we could comment a script by using `#` for a single line then why do you need 2 times ## when it could work from starting of it?? It should help you in shell script and should be considered as comment. let me know? – RavinderSingh13 May 29 '18 at 10:18
  • i want to comment from echo " till >>LogFile.txt as both of these are in different lines # operator can not be used as per my understanding – Hammad Ahmed May 30 '18 at 05:54
0

Don't use comments for configuration. Rewrite your script to allow for certain blocks to be configured.

: ${LOG_FILE:=LogFile.txt}

{
  echo "+++++++++++++++++++++"
  echo "doing some stuff"
} >> bills.txt

{
  echo "starting
to execute some commands"
  echo "----------------------"
} >> "$LOG_FILE"

ls 
cat someFile.txt| grep "search me"
{
  echo "search results found"
  echo "----------------------"
} >> "$LOG_FILE"
{
  echo "+++++++++++++++++++++"
  echo "doing some more stuff"
} >> bills.txt

some other commands...

{
  echo "finshing 
  script
   execution"
  echo "----------------------"
} >> "$LOG_FILE"

Now, if you want to disable writing to the log file, you just run your script with

LOG_FILE=/dev/null ./sampleScript.sh

instead of commenting the lines out.

chepner
  • 497,756
  • 71
  • 530
  • 681