Присвойте значения или строку переменной в сценариях Linux

Я пытаюсь назначить вывод basename команда файла для переменной "filename". paths файл, который содержит путь, например /root/home/david/mynote

$FILE это = mynote, grep чтобы получить полный путь /root/home/david/mynote а также basename это извлечь только mynote и назначить его переменной filename,

filename=basename `grep $FILE House/paths`

В приведенной выше командной строке значение filename всегда пусто, когда я вхожу echo $filename,

2 ответа

Это прекрасный пример, почему вы должны прекратить использовать устаревший синтаксис backtick в bash:

filename=$(basename $(grep $FILE House/paths))

См. http://www.gnu.org/software/bash/manual/bashref.html

Обратите внимание, что для защиты от путей, которые могут содержать пробелы, заключите некоторые элементы в двойные кавычки:

filename=$(basename "$(grep "$FILE" House/paths)")

Причина, по которой переменная пуста, заключается в следующем: когда оболочка видит

filename=basename `grep $FILE House/paths`
  1. оболочка сначала выполняет команду grep (предположим, для иллюстрации команда возвращает "/foo/bar/myfile")
  2. Затем оболочка пытается выполнить "/foo/bar/myfile", временно устанавливая переменную окружения filename со значением baseline на время этой команды - оболочка не содержит filename переменная.

Это спокойно задокументировано в справочнике bash в разделе Environment

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

В общем, в BASH вы сохраняете вывод команд в переменную одним из следующих способов:

foo=$(ls /usr)

или же

foo=`ls /usr`

Что касается вашего вопроса, если у вас есть файл с именем foo.txt чье содержимое выглядит так:

/usr/
/usr/games
/usr/games/cowthink
/usr/games/cowsay
/usr/games/fortune
/usr/games/enemylines7
/usr/games/enemylines3
/usr/lib32
/usr/lib32/libgdbm_compat.so.3.0.0
/usr/lib32/libfusion-1.2.so.9.0.1

тогда это должно делать то, что вам нужно:

while read FILE; do filename=`basename "$FILE"`; echo "$filename"; done < foo.txt

Если вместо этого вы хотите выполнить поиск определенного шаблона (например, "mynote") в файле, выполните:

grep mynote foo.txt|while read FILE; do filename=`basename "$FILE"`; echo "$filename"; done

ОБЪЯСНЕНИЕ:

while read FILE; do {something}; done < foo.txt

Эта команда читает каждую строку файла foo.txt и сохраняет его содержимое в переменную $FILE, Затем он выполняет {something} один раз для каждой строки файла.

В этом случае, {something} это команда:

filename=`basename "$FILE"`; echo "$filename"  

Оно бегает basename на содержание переменной $FILE and saves the result in the variable $filename, Notice the quotes (") вокруг $FILE, they ensure that the command works for file names containing spaces. Finally it uses echo to print the contents of $filename,


ОБНОВИТЬ:

After seeing your other question, I understand what you are trying to do. What you need is this:

filename=$(basename `grep $FILE CourseWork/paths`) 
Другие вопросы по тегам