Содержимое файла в переменной unix с символами новой строки

118

У меня есть текстовый файл test.txt со следующим содержанием:

text1
text2 

И я хочу присвоить содержимое файла переменной UNIX, но когда я сделаю это:

testvar=$(cat test.txt)
echo $testvar

результат:

text1 text2

вместо того

text1
text2 

Может ли кто-нибудь предложить мне решение этой проблемы?

Хьюго
источник

Ответы:

186

Присваивание не удаляет символы новой строки, это фактически echoделает это. Вам нужно просто заключить строку в кавычки, чтобы сохранить эти символы новой строки:

echo "$testvar"

Это даст желаемый результат. См. Следующую стенограмму демонстрации:

pax> cat num1.txt ; x=$(cat num1.txt)
line 1
line 2

pax> echo $x ; echo '===' ; echo "$x"
line 1 line 2
===
line 1
line 2

Причина , почему новые строки заменяются пробелами не полностью делать с echoкомандой, а это сочетание вещей.

Когда задана командная строка, bashразбивает ее на слова в соответствии с документацией для IFSпеременной:

IFS: Внутренний разделитель полей, который используется для разделения слов после раскрытия ... значение по умолчанию <space><tab><newline>.

Это означает, что по умолчанию любой из этих трех символов может использоваться для разделения вашей команды на отдельные слова. После этого разделители слов исчезли, все, что у вас осталось, это список слов.

Объедините это с echoдокументацией ( bashвнутренняя команда), и вы поймете, почему выводятся пробелы:

echo [-neE] [arg ...]: вывести аргументы, разделенные пробелами, за которыми следует новая строка .

Когда вы используете echo "$x", он заставляет всю xпеременную быть одним словом в соответствии с bash, следовательно, она не разбивается. Вы можете увидеть это с помощью:

pax> function count {
...>    echo $#
...> }
pax> count 1 2 3
3
pax> count a b c d
4
pax> count $x
4
pax> count "$x"
1

Здесь countфункция просто выводит количество заданных аргументов. 1 2 3И a b c dварианты показать его в действии.

Затем мы пробуем это с двумя вариантами xпеременной. Один без кавычек показывают , что есть четыре слова, "test", "1", "test"и "2". Добавление кавычек делает его одним словом "test 1\ntest 2".

paxdiablo
источник
Цитаты ... вот чего мне не хватало! Спасибо!
anonymite
Также стоит отметить: завершающие символы новой строки будут удалены самим оператором подстановки команд: попробуйте онлайн!
Иона
11

Это связано с переменной IFS (внутренний разделитель полей), которая содержит новую строку.

$ cat xx1
1
2

$ A=`cat xx1`
$ echo $A
1 2

$ echo "|$IFS|"
|       
|

Обходной путь - сбросить IFS, чтобы временно не содержать новую строку :

$ IFSBAK=$IFS
$ IFS=" "
$ A=`cat xx1` # Can use $() as well
$ echo $A
1
2
$ IFS=$IFSBAK

Чтобы ОТМЕНИТЬ это ужасное изменение для IFS:

IFS=$IFSBAK
DVK
источник
Я сделал это изменение, но теперь другие мои функции не работают, скажите мне, чтобы я сбросил его обратно?
Pooja25,
Если вам не нужно переходить к переменной, прямой однострочный:echo "$(IFS=''; cat text.txt)"
Кертис Яллоп,
10

Bash -ge 4 имеет встроенный mapfile для чтения строк из стандартного ввода в переменную массива.

help mapfile 

mapfile < file.txt lines
printf "%s" "${lines[@]}"

mapfile -t < file.txt lines    # strip trailing newlines
printf "%s\n" "${lines[@]}" 

Смотрите также:

http://bash-hackers.org/wiki/doku.php/commands/builtin/mapfile

Todd
источник
3

Просто если кого-то интересует другой вариант:

content=( $(cat test.txt) )

a=0
while [ $a -le ${#content[@]} ]
do
        echo ${content[$a]}
        a=$[a+1]
done
DerWilts
источник
3

Ваша переменная установлена ​​правильно testvar=$(cat test.txt). Чтобы отобразить эту переменную, содержащую символы новой строки, просто добавьте двойные кавычки, например

echo "$testvar" 

Вот полный пример:

$ printf "test1\ntest2" > test.txt
$ testvar=$(<test.txt)
$ grep testvar <(set)
testvar=$'test1\ntest2'
$ echo "$testvar"
text1
text2
$ printf "%b" "$testvar"
text1
text2
Kenorb
источник
0

envdirУтилита предоставляет простой способ сделать это. envdirиспользует файлы для представления переменных среды, с сопоставлением имен файлов с именами env var и сопоставлением содержимого файла со значениями env var. Если содержимое файла содержит символы новой строки, то env var.

См. Https://pypi.python.org/pypi/envdir

Крис Джонсон
источник