Файл вмісту в змінну unix з новими рядками


117

У мене є текстовий файл test.txt із наступним вмістом:

text1
text2 

І я хочу призначити вміст файлу змінної UNIX, але коли я це роблю:

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

результат:

text1 text2

замість

text1
text2 

Чи може хтось запропонувати мені рішення для цього?

Відповіді:


185

Завдання не видаляє символи нового рядка, це фактично робиться так 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".


Цитати ... ось чого мені не вистачало! Дякую!
анонім

Також варто відзначити: Останнє видалення нових рядків буде видалено самим оператором підстановки команд: Спробуйте в Інтернеті!
Іона

11

Це пов'язано із змінною IFS (Internal Field Separator), яка містить новий рядок.

$ 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)"
Curtis Yallop


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.