auino
auino

Reputation: 1656

Bash replace '\n\n}' string in file

I've got files repeatedly containing the string \n\n} and I need to replace such string with \n} (removing one of the two newlines).
Since such files are dynamically generated through a bash script, I need to embed replacing code inside the script.

I tried with the following commands, but it doesn't work:

cat file.tex | sed -e 's/\n\n}/\n}/g' # it doesn't work!
cat file.tex | perl -p00e 's/\n\n}/\n}/g' # it doesn't work!
cat file.tex | awk -v RS="" '{gsub (/\n\n}/, "\nb")}1' # it does work, but not for large files

Upvotes: 2

Views: 973

Answers (6)

mathiasrw
mathiasrw

Reputation: 618

If you have access to node you can use rexreplace

npm install -g regreplace

and then run

rexreplace '\n\n\}' '\n\}' myfile.txt

Of if you have more files in a dir data you can do

rexreplace '\n\n\}' '\n\}' data/*.txt

Upvotes: 0

Axeman
Axeman

Reputation: 29854

Nix-style line filters process the file line-by-line. Thus, you have to do something extra to process an expression which spans lines.

As mentioned by others, '\n\n' is simply an empty line and matches the regular expression /^$/. Perhaps the most efficient thing to do is to save each empty line until you know whether or not the next one will contain a close bracket at the beginning of the line.

cat file.tex | perl -ne 'if ( $b ) { print $b unless m/^\}/; undef $b; } if ( m/^$/ ) { $b=$_; } else { print; } END { print $b if $b; }'

And to clean it all up we add an END block, to process the case that the last line in the file is blank (and we want to keep it).

Upvotes: 1

Jahid
Jahid

Reputation: 22438

This should work:

cat file.tex | sed -e 's/\\n\\n}/\\n}/g'

if \n\n} is written as raw string.

Or if it's new line:

cat file.tex | sed -e ':a;N;$!ba;s/\n\n}/\n}/g'

Another method:

if the first \n is any new line:

text=$(< file.tex)
text=${text//$'\n\n}'/$'\n}'}
printf "%s\n" "$text" #> file

If the first \n is an empty line:

text=$(< file.tex)
text=${text//$'\n\n\n}'/$'\n\n}'}
printf "%s\n" "$text" #> file

Upvotes: 1

Borodin
Borodin

Reputation: 126742

This Perl command will do as you ask

perl -i -0777 -pe's/\n(?=\n})//g' file.tex

Upvotes: 1

Casimir et Hippolyte
Casimir et Hippolyte

Reputation: 89574

a way with sed:

sed -i -n ':a;N;$!ba;s/\n\n}/\n}/g;p' file.tex

details:

:a             # defines the label "a"
N              # append the next line to the pattern space
$!ba           # if it is not the last line, go to label a
s/\n\n}/\n}/g  # replace all \n\n} with \n}
p              # print

The i parameter will change the file in place. The n parameter prevents to automatically print the lines.

Upvotes: 1

Ed Morton
Ed Morton

Reputation: 203985

You didn't provide any sample input and expected output so it's a guess but maybe this is what you're looking for:

$ cat file
a
b

c

}
d

$ awk '/^$/{f=1;next} f{if(!/^}/)print "";f=0} 1' file
a
b

c
}
d

Upvotes: 3

Related Questions