Содержимое файла в переменной 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".


Цитаты ... вот чего мне не хватало! Спасибо!
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

Я сделал это изменение, но теперь другие мои функции не работают, скажите мне, чтобы я сбросил его обратно?
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


3

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

content=( $(cat test.txt) )

a=0
while [ $a -le ${#content[@]} ]
do
        echo ${content[$a]}
        a=$[a+1]
done

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

0

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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.