6

I came across this code from a textbook; the book only says that 1,/^[ ]*$/d means “Delete from line 1 until the first blank line.” What does each character specifically mean?

ed $1 << EOF
    1,/^[ ]*$/d
    w
    q
EOF
Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
Jack Chen
  • 169

2 Answers2

4

1,/.../ means the range from the 1st line to a line matching the pattern between the /.

/^[ ]*$/ matches a line that contains 0 or any number of spaces [ ]* from the beginning ^ to the end $ of the line.
It is unclear if the code in the question is intentional and if it is an exact copy from the book. Brackets around a single space are not necessary. Maybe the original author wanted to have a space and a tab character between the brackets, which could be replaced with the character class [[:blank:]].

d is the command to delete the line

w write the file

q quit the editor

Those commands are sent to ed via a here document, indicated by the << EOF. The EOF string is a semi-arbitrary name that is paired to the other EOF four lines down. Leaving the EOF unquoted means that any variables in the intervening lines will be expanded.

The other thing to note here is the example's unquoted $1. The ed command/script will execute against the first positional parameter (argument to the script or function) subject to further whitespace splitting and filename generation. The argument really should be quoted. For further reading, see Why does my shell script choke on whitespace or other special characters? and Security implications of forgetting to quote a variable in bash/POSIX shells.

Bodo
  • 6,068
  • 17
  • 27
  • Assuming the [ ] does contain a space and a tab, then it could be replaced by [[:blank:]], which would allow "blank" characters. The line is, in a sense "blank" if it contains only characters matching [[:blank:]] (or contains nothing). I'm not certain if this was tho textbook's intention, i.e. the connection between its "blank line" and [[:blank:]], or whether it was just my mind making that connection. – Kusalananda Jun 06 '19 at 15:40
  • And, if the brackets contain only a space (rather than a space and a tab), then they (the brackets) can be omitted: just do 1,/^ *$/d. – G-Man Says 'Reinstate Monica' Jun 07 '19 at 00:02
3

Command and input

The $1 is the file name to be edited and everything between the EOFs are commands to ed.

Blow by blow description of 1,/^[ ]*$/d

  • 1, start from line 1 and in this case continue until first occurrence of search string
  • / indicates we are about to search for a string
  • ^ indicates we want to match the start of the line in the file
  • [ indicates we are about to specify many characters
  • '' we want to match a space - normally there would be more characters here
  • ] finished specifying characters
  • * we want to match 0 or more spaces (or whatever characters between [])
  • $ until the end of the line in the file
  • / closing the search
  • d delete the line

Then the next line w writes the changes, and q quits ed.

Effect

If the file's ($1) line one is empty or has only spaces (no tabs) then it will be removed.

  • (1) No, 1,g/^[ ]*$/d is not the same as 1,/^[ ]*$/d.  1,g/^[ ]*$/d is the same as 1g/^[ ]*$/d (i.e., the comma doesn’t change anything); that command deletes the first line if it is “blank”, but no others. (2) What are you saying about “you need to skip to the last line specified?” – G-Man Says 'Reinstate Monica' Jun 06 '19 at 23:54
  • (1) I did say in this case (2) 1,3 won't work unless you enter the ed command 3 beforehand. – Colin Pearse Jun 07 '19 at 02:26
  • (2) to clarify.... 3 goes (skips) to the nth line. – Colin Pearse Jun 07 '19 at 02:34
  • (1) No, 1,g/^[ ]*$/d is not the same as 1,/^[ ]*$/d.  They will produce the same result if the first line of the buffer is “blank”.  Since the question does not present any sample input (buffer contents), I don’t understand how you can justify saying “in this case”.  (2) I understand that, if 3 is typed as a command into ed, it will move you to line 3.  But you don’t need to do that before running a command that begins 1,3. … (Cont’d) – G-Man Says 'Reinstate Monica' Jun 07 '19 at 03:59
  • (Cont’d) …  It is, of course, true that ed is a line editor, the ed command 3 will skip to line 3, and the g command is very useful.  I see very little else in your “Notes that is correct. – G-Man Says 'Reinstate Monica' Jun 07 '19 at 03:59
  • Point taken, I've remove the note – Colin Pearse Jun 07 '19 at 04:18
  • 1,/search/ is a range; it does not (necessarily) operate only on line 1. The important part there is the comma. – Jeff Schaller Jun 07 '19 at 04:27
  • ok, changed 1, to specify that it's a range – Colin Pearse Jun 07 '19 at 05:35