简体   繁体   中英

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

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

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.

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).

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

这个Perl命令可以按照你的要求执行

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM