Предположим, у вас есть этот файл:
$ 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
Существует четыре элемента, которые изменят значение вывода файла, читаемого многими решениями Bash:
- Пустая строка 4;
- Начальные или конечные пробелы в двух строках;
- Сохранение значения отдельных строк (т. Е. Каждая строка является записью);
- Строка 6 не заканчивается CR.
Если вы хотите, чтобы текстовый файл построчно включал пустые строки и завершающие строки без CR, вы должны использовать цикл while и иметь альтернативный тест для последней строки.
Вот методы, которые могут изменить файл (по сравнению с тем, что cat
возвращает):
1) Потерять последнюю строку, а также начальные и конечные пробелы:
$ 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'
(Если вы сделаете это while IFS= read -r p; do printf "%s\n" "'$p'"; done </tmp/test.txt
, вы сохраните начальные и конечные пробелы, но все равно потеряете последнюю строку, если она не заканчивается на CR)
2) Использование процесса подстановки с cat
волей читает весь файл за один раз и теряет значение отдельных строк:
$ 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'
(Если вы удаляете "
из $(cat /tmp/test.txt)
файла слово за словом, а не одним глотком. Также, вероятно, не то, что предназначено ...)
Самый надежный и простой способ прочитать файл построчно и сохранить все пробелы:
$ 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'
Если вы хотите удалить ведущие и торговые пробелы, удалите IFS=
часть:
$ 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'
(Текстовый файл без завершения \n
, хотя и довольно распространенный, считается поврежденным в POSIX. Если вы можете рассчитывать на конечный трейлинг, который \n
вам не нужен || [[ -n $line ]]
в while
цикле.)
Больше на BASH FAQ