Використовуйте 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


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

@jOh --- зауважте, що sedтут працює не "строкова змінна" (?), а стандартний вхід --- який саме має бути.
— Рмано

Я думаю, що я роблю запит на функцію до sed devs
— j0h

4
@ j0h це не має нічого спільного sed, це питання про те, як оболонка перенаправляє введення. sedмає справу з потоками введення, і він читає їх через свій стандартний вхід. Будь вони файли чи ні, не має значення. Він може приймати що завгодно, якщо це відбувається через стандартний ввід.
— тердон

38

Це не має нічого спільного з sedтаким, воно стосується будь-якої програми, яка читає стандартний вхід. У будь-якому випадку, що ви шукали

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

Немає підстав для збереження в іншій змінній, нічого, що ви зробите таким чином, не вплине на значення, збережене в змінній. Для цього вам потрібен оператор призначення ( =). Синтаксис, який використовується вище, називається "тут рядок" і характерний для bash, ksh та zsh. Він служить для передачі значення змінної як введення програмі, яка читає зі стандартного вводу.

Я написав відповідь на U&L, в якій перераховані всі різні оператори оболонок, як цей. Можливо, ви захочете поглянути.

Зауважте, що ви також могли це зробити

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

Нарешті, вам насправді для цього зовсім не потрібно sed. Ви можете зробити все це в баші безпосередньо:

echo "${PATH//:/ }"

Сказане вище - це конструкція заміни баша. З огляду на змінне $var, шаблон patі заміну ( rep), щоб замінити всі входження patз rep, ви могли б зробити

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

Те ж саме з однією косою рисою замінює лише перше виникнення:

echo "${var/pat/rep}"

2
Дякуємо за "конструкцію заміни bash". Мені вдалося використовувати: "$ {1 / від / до}" у функції Bash для зміни першого аргументу на наступні параметри.
— AAAfarmclub
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.