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