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

30

Мне сказали, что это возможно, но без единого рабочего примера, который 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
источник
1
x=$(echo "$x" | sed 's/:/ /g')?
Heemayl

Ответы:

16

Может быть:

~$ x="$PATH"
~$ x="$(echo $x | sed 's/:/ /g')"
~$ echo "$x"
/usr/local/bin /usr/bin /bin /usr/local/games /usr/games
bolichep
источник
@jOh --- обратите внимание, что sedздесь работает не с «строковой переменной» (?), а со стандартным вводом --- что и должно быть.
Rmano
я думаю, что я сделаю запрос функции для разработчиков
dev
4
@ j0h это не имеет никакого отношения sed, вопрос в том, как оболочка перенаправляет ввод. sedимеет дело с входными потоками и читает их через стандартный ввод. Будь то файлы или нет, не имеет значения. Он может принимать что угодно, если он поступает через стандартный ввод.
тердон
38

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

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

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

Я написал ответ на U & 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
источник
2
Спасибо за 'замену конструкции bash'. Мне удалось использовать: «$ {1 / from / to}» в функции Bash, чтобы изменить первый аргумент в последующие параметры.
AAAfarmclub