Giả sử bạn có tệp này:
$ cat /tmp/test.txt
Line 1
Line 2 has leading space
Line 3 followed by blank line
Line 5 (follows a blank line) and has trailing space
Line 6 has no ending CR
Có bốn yếu tố sẽ thay đổi ý nghĩa của đầu ra tệp được đọc bởi nhiều giải pháp Bash:
- Dòng trống 4;
- Không gian hàng đầu hoặc dấu trên hai dòng;
- Duy trì ý nghĩa của các dòng riêng lẻ (nghĩa là mỗi dòng là một bản ghi);
- Dòng 6 không được kết thúc bằng CR.
Nếu bạn muốn dòng tệp văn bản theo dòng bao gồm dòng trống và dòng kết thúc không có CR, bạn phải sử dụng vòng lặp while và bạn phải có một bài kiểm tra thay thế cho dòng cuối cùng.
Dưới đây là các phương pháp có thể thay đổi tệp (so với những gì cat
trả về):
1) Mất dòng cuối cùng và khoảng trắng ở đầu và cuối:
$ while read -r p; do printf "%s\n" "'$p'"; done </tmp/test.txt
'Line 1'
'Line 2 has leading space'
'Line 3 followed by blank line'
''
'Line 5 (follows a blank line) and has trailing space'
(Nếu bạn while IFS= read -r p; do printf "%s\n" "'$p'"; done </tmp/test.txt
thay vào đó, bạn giữ nguyên các khoảng trắng ở đầu và cuối nhưng vẫn mất dòng cuối cùng nếu nó không bị chấm dứt với CR)
2) Sử dụng thay thế quá trình với cat
sẽ đọc toàn bộ tệp trong một ngụm và mất ý nghĩa của các dòng riêng lẻ:
$ for p in "$(cat /tmp/test.txt)"; do printf "%s\n" "'$p'"; done
'Line 1
Line 2 has leading space
Line 3 followed by blank line
Line 5 (follows a blank line) and has trailing space
Line 6 has no ending CR'
(Nếu bạn xóa "
từ $(cat /tmp/test.txt)
bạn đọc tệp từng chữ chứ không phải một ngụm. Cũng có thể không phải là những gì được dự định ...)
Cách mạnh mẽ và đơn giản nhất để đọc từng dòng tệp và giữ tất cả khoảng cách là:
$ while IFS= read -r line || [[ -n $line ]]; do printf "'%s'\n" "$line"; done </tmp/test.txt
'Line 1'
' Line 2 has leading space'
'Line 3 followed by blank line'
''
'Line 5 (follows a blank line) and has trailing space '
'Line 6 has no ending CR'
Nếu bạn muốn loại bỏ không gian hàng đầu và giao dịch, hãy xóa IFS=
phần:
$ while read -r line || [[ -n $line ]]; do printf "'%s'\n" "$line"; done </tmp/test.txt
'Line 1'
'Line 2 has leading space'
'Line 3 followed by blank line'
''
'Line 5 (follows a blank line) and has trailing space'
'Line 6 has no ending CR'
(Một tệp văn bản không có dấu chấm dứt \n
, trong khi khá phổ biến, được coi là bị hỏng trong POSIX. Nếu bạn có thể tin tưởng vào dấu vết \n
bạn không cần || [[ -n $line ]]
trong while
vòng lặp.)
Thông tin khác tại Câu hỏi thường gặp về BASH