On Wed, 28 Oct 2026 at 09:29, Mark Symmes <[email protected]> wrote:
> a 'dangling line-feed' *[at EOF]*
Calling it "dangling" is completely backwards.
The newline is not "dangling", it's mandatory.
If anything is "dangling", it's any text after the last newline.
In the POSIX worldview, newlines are line *_terminators_* rather than line
*_separators_*.
A line without a newline is incomplete; a fragment.
A non-empty file that lacks a final newline is not a valid
(standards-compliant) text file.
If there's an incomplete fragment of a line at the end, consumer behavior
will vary.
Most will try to make the best of it, but, for example:
* "cat" will make one line from the trailing line fragment in one file and
the first line in the next file
* "grep" might not bind "$" to the last position in the trailing fragment
* "wc -l" only counts whole lines (and ignores any fragment)
* output to a terminal may result in the prompt not displaying properly
The proof is running a python3 script vs a bash awk script.
>
Bash and awk and wc have their behaviour dictated by standards.
As for Python, that depends how it's used. I'm guessing something like:
with open(filename, "r") as fi:
lines = fi.read().split("\n")
print(f"{filename} has {len(lines)} lines")
That idiom is, despite being common, broken.
Please use .splitlines() rather than .split("\n"), which will avoid
synthesizing imaginary blank lines (and will work with DOS text files too).
-Martin
PS: I'd be tempted to write:
with open(filename, "r") as fi:
lines = fi.read().split("\n")
fragment = lines.pop()
print(f"{filename} has {len(lines)}{"½" if fragment else ""} lines")
PPS: if a text editor fails to write a newline at the end of a file, please
fix its configuration settings.