LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   prevent sed from replacing \n with newline (http://www.linuxquestions.org/questions/programming-9/prevent-sed-from-replacing-%5Cn-with-newline-772210/)

map250r 11-28-2009 11:41 PM

prevent sed from replacing \n with newline
 
I'm writing a script to replace some text that exists in about 50 .lex, .y, and .cc source code files, sometimes more than once in a file. Sometimes the text is in a multiline C comment, and other times it's within a multiline C string.

I use sed to grab the start and end of each line and wrap the new text in the old whitespace and/or quotes and \n. Problem is, sed is changing the characters \n into a newline.

Is there a way to tell sed to not process escape sequences? I tried using several variations of
Code:

sed -e 's/\\n/\\\\n/;'
to no avail. Or could it be bash that is the culprit?

I would give up on the script and do it by hand, but this is something that I must do from time to time.

Here's the function which replaces the first occurrence found:
Code:

function replacetext {
        # $1 is file
        line=`grep -nm 1 $findstring $1 | cut -s -d: -f1`
        text=`grep -m 1 $findstring $1`

        pre=`echo $text | sed -e "s/^\(.*\)$findstring.*$/\1/;"`
        post=`echo $text | sed -e "s/^.*$findstring\(.*\)$/\1/;" -e 's/\\n/\\\\n/;'`
        echo "text |$text| pre |$pre| post |$post| line |$line|"
        head -n$(($line-1)) $1 > $1.tmp
        sed -e "s/^/$pre/g;" -e "s/$/$post/g;" < $newDfile >> $1.tmp
        tail -n+$(($line + 8)) $1 >> $1.tmp  #original text is 8 lines
        mv -f $1.tmp $1
}

When $post is printed by echo, it shows the \n - but by the time the file is on disk, it becomes a newline. What should I do to ensure that it stays as the characters \n?

ghostdog74 11-28-2009 11:43 PM

show some sample input. describe your output.

map250r 11-29-2009 12:24 AM

Quote:

Originally Posted by ghostdog74 (Post 3772901)
show some sample input. describe your output.

input is similar to:
Code:

/******************************************************************************
  DISCLAIMER:
  blah
  blah
  blah
  blah
  blah
  blah
  blah
******************************************************************************/

void printYaccIncDefs( /* ARGUMENTS                          */
 FILE * yaccFile,      /* YACC file to print in              */
 char * baseFileName)  /* base file name for including header */
{
  fprintf(yaccFile,
"/************************************************************************\n"
"  DISCLAIMER:\n"
"  blah\n"
"  blah\n"
"  blah\n"
"  blah\n"
"  blah\n"
"  blah\n"
"  blah\n"
"************************************************************************/\n"
"\n"
"#include <string.h>  // for strlen, strcpy, strcat\n"
"#include <stdio.h>  // for fopen, etc.\n"
"#include <stdlib.h>  // for exit\n"
"#include \"%s.hh\"\n", baseFileName);
  fprintf(yaccFile,
"\n"
"#define YYERROR_VERBOSE\n"
"#define YYDEBUG 1\n"
"\n");
}

The output would be the same, except it would show a gpl v3 copyleft notice instead of DISCLAIMER blah blah blah.

I think that in some files the string is printed when the program runs, rather than being printed into a comment in a source code file.

HTH

Kenhelm 11-29-2009 04:54 AM

These work for me using GNU sed in bash
Code:

sed 's/\\n/\\\\n/'      # Inside $(.......)
sed 's/\\n/\\&/'        # Inside $(.......)

sed 's/\\\n/\\\\\\\n/'  # Inside backticks `.......`
sed 's/\\\n/\\\\&/'      # Inside backticks `.......`
# One of several reasons why $(....) is better than backticks.


This is a more general method of escaping special characters in variables which will be used inside sed.
The variables should be inside double quotes when used in the sed expressions so spaces do not need escaping.
Code:

# For basic regular expressions used by sed
var_esc=$(echo "$var" | sed 's/[][*.^$\&/]/\\&/g' )
# It escapes the characters ][*.^$\&/
# e.g. $x\n"hello"&[]/d  becomes
#  \$x\\n"hello"\&\[\]\/d
# Quotes are special to bash not sed, so don't need escaping here.

# For extended regular expressions used by sed -r
var_esc=$(echo "$var" | sed 's/[][{}()+?*.^$\&/]/\\&/g' )
# It escapes the characters ][{}()+?*.^$\&/


map250r 11-29-2009 08:16 AM

Thanks, Kenhelm. I had changed the number of backslashes in the replacement string, but didn't think to change the number in the string being searched for. I just assumed it was working. :o


All times are GMT -5. The time now is 05:34 PM.