Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have a javascript file with two new lines after a particular word "[FACT]", I want to replace it with one newline. I need to do it in bash script. Normally, I would have used sed but it turns out that sed is not good for dealing with newlines in input. (correct me if i am wrong).

To do it programatically, I can employ shell script or javascript/Java etc. for this purpose, but what will be a good solution from the perspective of software engineering (maintainability, portability etc.).

sed 's/\[FACT\]\/n/\[FACT\]/g' file.js
share|improve this question
    
Why does it need to be done programmatically and not with a text editor? Does something keep putting the extra newline back in? –  jordanm Oct 30 '13 at 22:44
    
@jordanm This is part of a build process which will be used repeatedly for different files. The auto-formatter tool adds an extra line after [FACT] and I want to remove that extra line while keeping other features of auto-formatter. –  Asad Iqbal Oct 30 '13 at 23:07

2 Answers 2

Portability? Text processing? Perl of course:

perl -n0777e 's{\n+}{\n}g' your_file

where -0777 instructs Perl to read the whole file in at once so that successive new lines can be found by Perl.

The above would remove all duplicate newlines. To remove only those after [FACT], you can do:

perl -n0777e 's{\[FACT\]\n+}{\n}g' your_file
share|improve this answer
    
To augment @Joseph's example, you can use the following one-liner to modify the file in place while creating a backup copy (.orig extension): perl -pi'.orig' -n0777e 's{(.*FACT)\n+}{\1\n}g' /tmp/file –  troydj Oct 31 '13 at 0:11
    
@troydj You need ...{$1\n}g instead of ...{\1\n}g. Perl uses \1 as a backreference only on the "left side" of the substitution. The "right side" should contain normal Perl variables (hence $1). As it stands \1 on the right side will be a reference to an anonymous scalar containing 1. –  Joseph R. Oct 31 '13 at 21:11

I am assuming that "two new lines" mean \n\n and not two blank lines following the line with [FACT] (which would be three newlines). Either way, the sed will work as it strips only the first newline after [FACT].

$ echo -e '[FACT]\n\nend'
[FACT]

end

This will search for lines ending in [FACT] and for each line that matches we use N to append the next line into the current pattern space retaining the newline that sed generally strips out of the pattern space.

$ echo -e '[FACT]\n\nend' |sed '/\[FACT\]$/ { N; s/\n// }'
[FACT]
end

If [FACT] doesn't specifically have to be at the end of the line, remove the $ from the command.

Please note that this technically strips the newline from the end of the line that contains [FACT] so it technically concatenates two lines into one:

$ echo -e '[FACT]\nhelp\nend' 
[FACT]
help
end

$ echo -e '[FACT]\nhelp\nend' |sed '/\[FACT\]$/ { N; s/\n// }'
[FACT]help
end
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.