Заменить одного персонажа другим в 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:

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


Хотя это работает для вопроса, как он был задан, он менее общий, чем принятый ответ (который работает на замену символов, а также на произвольные строки), а также включает и внешнюю команду.
Дан Даскалеску

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'



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'

2
Уже есть двухлетний ответ, который решает проблему с sed. Цитаты не имеют значения.
chepner
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.