Использовать sed для строковой переменной, а не для файла

16

Мне сказали, что это возможно, но без одного рабочего примера, что sed может читать из строковой переменной без необходимости ввода входного файла. Мне еще нужно заставить его работать. Для общей безопасности я пишу переменную $PATH в другую переменную, так как мне это не нравится, потому что мне не нужны другие проблемы, пока я точно не знаю, как это сделать.

Рассмотрим следующее:

~$x=$PATH
~$sed -i 's/:/ /g' $x

это не с: Нет такого файла или каталога.

Вот некоторые другие, которые я пробовал:

~$ sed -i 's/:/ /g' | (read x) 
sed: no input files
~$ sed -i 's/:/ /g' | (read $x) 
bash: read: '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games': not a valid identifier
sed: no input files
~$ sed -i 's/:/ /g' | $(read x) 
sed: no input files
~$ sed -i 's/:/ /g' | $(read $x) 
bash: read: '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games': not a valid identifier
sed: no input files
~$ sed -i 's/:/ /g' < $(read $x) 
bash: read: '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games': not a valid identifier
bash: $(read $x): ambiguous redirect
~$ sed -i 's/:/ /g' < read $x 
bash: read: No such file or directory
~$ sed -i 's/:/ /g' < (read x) 
bash: syntax error near unexpected token '('
~$ sed -i 's/:/ /g' < $((read x)) 
bash: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games: syntax error: operand expected (error token is "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games")
~$ sed -i 's/:/ /g' < $((read $x)) 
bash: read /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games: division by 0 (error token is "usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games")
~$ sed -i 's/:/ /g' << $((read $x)) 
> ;^C
~$ sed -i 's/:/ /g' << $(read $x)
> ;^C
~$ sed -i 's/:/ /g' $x
sed: can't read /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games: No such file or directory
~$ sed -i 's/:/ /g' < $x
bash: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games: No such file or directory
~$ sed -i 's/:/ /g' < echo $x
bash: echo: No such file or directory
~$ sed -i 's/:/ /g' |  echo $x
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
sed: no input files

Может ли это работать? Я бы предпочел не писать файлы, которые мне не нужны, поэтому я могу использовать sed. Для этого конкретного примера, если ~$x=$PATH ~$sed -i 's/:/ /g' $x действительно работал так, как я бы надеялся, я бы получил:

/usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /usr/games /usr/local/games

, который я мог бы затем присвоить переменной и использовать в будущих командах, например ls $x

    
задан j0h 10.03.2015 в 22:21
источник

2 ответа

13

Может быть:

~$ x="$PATH"
~$ x="$(echo $x | sed 's/:/ /g')"
~$ echo "$x"
/usr/local/bin /usr/bin /bin /usr/local/games /usr/games
    
ответ дан bolichep 10.03.2015 в 22:38
источник
26

Это не имеет никакого отношения к sed как таковой, оно применимо к любой программе, которая читает стандартный ввод. В любом случае, вы искали

sed 's/:/ /g' <<<"$PATH"

Нет причин для сохранения в другой переменной, ничто из этого не повлияет на значение, хранящееся в переменной. Для этого вам нужен оператор присваивания ( = ). Использованный выше синтаксис называется «здесь строка» и относится к bash, ksh и zsh. Он служит для передачи значения переменных в качестве ввода в программу, которая читает со стандартного ввода.

Я написал ответ на U & amp; L , в котором перечислены все различные операторы оболочки, подобные этому. Возможно, вы захотите посмотреть.

Обратите внимание, что вы также могли бы сделать

echo "$PATH" | sed 's/:/ /g' 

Наконец, для этого вам действительно не нужно sed . Вы можете сделать все это прямо в bash:

echo "${PATH//:/ }"

Вышеупомянутая конструкция замены bash. Учитывая переменную $var , шаблон pat и замену ( rep ), чтобы заменить все вхождения pat на rep , вы сделали бы

echo "${var//pat/rep}"

То же самое с единственной косой чертой заменяет только первое вхождение:

echo "${var/pat/rep}"
    
ответ дан terdon 10.03.2015 в 23:34