Question

I have two files, both of which appear to my eyes as follows.

a

a

The difference is that I created one of them with vim and the other with the wine version of Notepad. I wrote the following script to print each line of these files at a time, more or less emulating cat (That's not my end goal, of course, but it's the simplest example I've thought of.).

#!/usr/bin/env bash

readarray -t list_file < "$1"

for line in "${list_file[@]}"
do
        echo "line content: \"$line\""
done

Expectedly, with the file created by vim (5 bytes as expected: a[newline][newline]a[newline]) as $1, it outputs this.

line content: "a"
line content: ""
line content: "a"

Unexpectedly, with the file created by Notepad (It's 6 bytes; I'm not sure why.) as $1, it outputs this. Why does it do this?

"ine content: "a
"ine content: "
line content: "a"

I also tried doing this completely differently, but the following script has exactly the same problem.

#!/usr/bin/env bash

for line_number in $(eval echo {1..$(wc -l < "$1")})
do
  echo "line content: $(sed -n "${line_number}p" "$1")"
done

What is the matter with these scripts that causes them to behave like this with the Notepad-created file?

Was it helpful?

Solution

The file created by vim has lines ending with LF, as on Unix. The file created with Notepad has lines ending with CR LF, as on DOS/Windows. bash uses LF as its line delimiter, so when it reads from the second file it leaves the CR at the end of each line. When you echo this character, it causes the cursor to return to the left margin, without advancing to the next line.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top