-1

I am trying to delete all empty lines after line number 3, till the end of the file:

cat ${File}
1

2
3


4

5

5



6
7



8
9


sed -e '3,${s~^$~~g}' ${File}
1

2
3


4

5

5



6
7



8
9

Observation: No change in the output.

Desired Output

1

2
3
4
5
5
6
7
8
9

Any Suggestions?

0

5 Answers 5

8

try:

sed '4,$ {/^$/d}' infile

start from the 4th line until end of the file, delete the empty lines.

The problem with your command is that you replace empty line again with empty string in s~^$~~g (which is same as s~^$~~) and you are not deleting it.

Note: also since you use different delimiter other than default slash /, to use this style ~^$~d you need to escape the first ~ to tell sed that is not part of your regex:

sed -e '4,${ \~^$~d }' infile

see man sed under "Addresses" about it:

\cregexpc Match lines matching the regular expression regexp. The c may be any character.


In case you wanted to delete empty lines as well as the lines containing only whitespaces (Tabs/Spaces), you can do:

sed '4,${ /^[[:blank:]]*$/d }' infile
2
  • Regarding delimeter TextWithPipe="Alpha|Beta|Gamma"; ReplacementTextWithPipe="Delta"; echo "${TextWithPipe}" | sed "s|Beta|${ReplacementTextWithPipe}|g" gives desired output Alpha|Delta|Gamma. But according to you, it should not work as I am using a differnt delimiter? Commented Feb 22, 2021 at 16:12
  • @Porcupine that's substitution for the s command, which is different from what I said. /regex/ is for regex match and anything other than / for that you must escape the first character Commented Feb 22, 2021 at 16:46
7

Another awk solution:

awk 'NR<=3||NF' file

This will print all lines where either the line number is smaller or equal 3, or which have at least one "field", defined by default as at least one non-blank character. This way, you can also exclude lines that contain no "text" but are only "visually" empty, i.e. that still contain space or tabs.

4
sed '1,3b;/./!d'

Branch in range 1,3 or delete if empty.

3

You were almost there. Just needed to add the following steps.

sed -ne '4,${s~^$~~;t};p' < "${File}"
  • select the range 4,$
  • try the dummy substitution s/^$//
  • in case the s/// succeeds, skip to next record t
  • else fall back n print for either these in-range nonempty lines or all out-of-range lines };p
0
2

an awk solution:

awk '((NR > 3 && $0!~/^$/) || NR <= 3) { print }' file
1
  • 1
    awk 'NR<3 || /./' can be simplified to this. Commented Feb 22, 2021 at 14:23

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.