Заменить одного персонажа другим в Bash

223

Мне нужно иметь возможность сделать, это заменить пробел ( ) с точкой ( .) в строке в Bash.

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

Брайан Лэйшман
источник

Ответы:

390

Используйте встроенную замену строки оболочки. Пример:

foo="  "

# replace first blank only
bar=${foo/ /.}

# replace all blanks
bar=${foo// /.}

См. Http://tldp.org/LDP/abs/html/string-manipulation.html для получения дополнительной информации.

Брайан Клаппер
источник
1
Хотя это решение хорошо при работе с короткими строками (частый случай, я думаю), можно предпочесть trдлинные строки. В моей системе trвыигрывает у bash, начиная со строк, содержащих больше 1000символов. Похоже, сложность времени bash хуже, чем линейная. Небольшой тест: x="$(tr -dc 'a-z \n' </dev/urandom | head -c1M)"; time y="$(tr ' ' \\- <<< "$x")"; time z="${x// /-}". С длиной строки 1M (= 2 ^ 20) trвзял 0.04sи bash 5.0.11 взял 17s. С 2M trвзял 0.07s(ожидалось), но bash взял 69s(в 4 раза больше длины в два раза).
Socowi
@Socowi Игра с 1Mb, хранящимся в переменной, не совсем обычна! До 10 Кбайт, кажется, Bash остается быстрее, чем разветвление tr! ... В зависимости от доступной памяти и ресурсов hw ... Но вы правы !: В зависимости от вида работы, выделенные инструменты остаются более эффективными!
Ф. Хаури
Для экранированных символов, таких как символы новой строки, обязательно выполните поиск$'\n'
user2561747
75

Вы можете использовать tr, как это:

tr " " .

Пример:

# echo "hello world" | tr " " .
hello.world

От man tr:

ОПИСАНИЕ
     Преобразование, сжатие и / или удаление символов из стандартного ввода, запись в стандартный вывод.

aioobe
источник
Хотя это работает для вопроса, как он был задан, он менее общий, чем принятый ответ (который работает на замену символов, а также на произвольные строки), а также включает и внешнюю команду.
Дан Даскалеску
2
С другой стороны, он работает с файлом 2 ГБ, не загружая все это в память.
aioobe
Вопрос был о «строке в bash», а не о произвольно больших файлах.
Дан Даскалеску
52

В bash вы можете выполнить замену шаблона в строке с помощью ${VARIABLE//PATTERN/REPLACEMENT}конструкции. Используйте только /и не //заменять только первое вхождение. Шаблон является шаблоном подстановки, как глобусы файлов.

string='foo bar qux'
one="${string/ /.}"     # sets one to 'foo.bar qux'
all="${string// /.}"    # sets all to 'foo.bar.qux'
Жиль "ТАК - перестань быть злым"
источник
24

Попробуй это

 echo "hello world" | sed 's/ /./g' 
обкрадывать
источник
6

Используйте подстановку параметров:

string=${string// /.}
Фриц Г. Мехнер
источник
4

Попробуйте это для путей:

echo \"hello world\"|sed 's/ /+/g'|sed 's/+/\/g'|sed 's/\"//g'

Он заменяет пространство внутри строки в двойных кавычках на +пение, затем заменяет +знак обратной косой чертой, а затем удаляет / заменяет двойные кавычки.

Я должен был использовать это, чтобы заменить пробелы в одном из моих путей в Cygwin.

echo \"$(cygpath -u $JAVA_HOME)\"|sed 's/ /+/g'|sed 's/+/\\/g'|sed 's/\"//g'
dsrdakota
источник
2
Уже есть двухлетний ответ, который решает проблему с sed. Цитаты не имеют значения.
chepner