Jeśli mam plik input.txt
zawierający:
hello
world
!
Następnie wykonanie polecenia bash echo $(cat input.txt)
wyświetli to:
hello world !
Dlaczego i jak mogę to naprawić, aby wyświetlało dokładnie to, co jest w pliku, jak jest w pliku?
Jeśli mam plik input.txt
zawierający:
hello
world
!
Następnie wykonanie polecenia bash echo $(cat input.txt)
wyświetli to:
hello world !
Dlaczego i jak mogę to naprawić, aby wyświetlało dokładnie to, co jest w pliku, jak jest w pliku?
Odpowiedzi:
Jeśli użyjesz
echo "$(cat input.txt)"
będzie działać poprawnie.
Prawdopodobnie dane wejściowe echa są oddzielone znakami nowej linii i będzie to obsługiwać jako osobne polecenia, więc wynik będzie bez znaków nowej linii.
echo "$(date) something"
Usuwa końcowy znak nowej linii z wyjścia date, dzięki czemu echo wypisuje datę i „coś” w tym samym wierszu. Jeśli chcesz zapisać plik lub dane wyjściowe polecenia „tak jak jest”, użyj mapfile ( help mapfile
) read -rd ''
lub pętli odczytu while.
Cytat ze strony podręcznika bash, sekcja Command Substitution
:
Osadzone znaki nowej linii nie są usuwane, ale mogą zostać usunięte podczas dzielenia słów.
Nieco dalej, ta sama sekcja:
Jeśli podstawienie pojawia się w podwójnych cudzysłowach, dzielenie słów i rozwijanie nazw ścieżek nie są wykonywane w wynikach.
Właśnie dlatego echo "$(cat /etc/passwd)"
działa.
Ponadto należy pamiętać, że podstawienie polecenia według specyfikacji POSIX usuwa końcowe znaki nowego wiersza:
$ echo "$(printf "one\ntwo\n\n\n")"
one
two
W związku z tym wysyłanie pliku przez $(cat file.txt)
może prowadzić do utraty końcowych znaków nowego wiersza, co może stanowić problem, jeśli integralność całego pliku ma priorytet.
Możesz zachować nowe wiersze, na przykład ustawiając IFS na pusty:
$ IFS=
$ a=$(cat links.txt)
$ echo "$a"
link1
link2
link3