Linux Momonga является японский GNU/дистрибутив Linux, что мощная поддержка функций языка программирования Ruby и его использования сильно защищена. Один проект, который разрабатывается командой Momonga, является библиотекой-оболочкой, которая позволяет пользователю использовать об/мин от Ruby.
Можно использовать AWK
awk '{gsub(/-/,".",$1);print}' infile
Объяснение
awk
разделяет строку на пробеле по умолчанию. Таким образом, первый столбец строки ($1
в awk
- ese), будет тот, относительно которого Вы хотите выполнить замены. С этой целью можно использовать:
gsub(regex,replacement,string)
выполнить необходимую замену.
Отметьте это gsub
поддерживается только для gawk
и nawk
но на многих современных дистрибутивах awk
softlink к gawk
.
Если Вы должны сделать замены относительно первого поля, лучше всего должны использовать awk решение Rahul, но остерегаться, оно может влиять на интервал (поля переписываются с одиночным пробелом, промежуточным их).
Можно избежать его путем записи его вместо этого:
perl -pe 's|\S+|$&=~tr/./-/r|e' file
-p
флаг означает, "читает входной файл линию за линией и печатают каждую строку после применения сценария, данного -e
". Затем замена (s|pattern|replacement|
) первая последовательность непробелов (\S+
) с подобранным шаблоном ($&
) после замены всеми .
с -
. Прием должен использовать s|||e
где e
оператор оценит выражение как замену. Так, у Вас может быть одна замена (tr/./-/
) относившийся соответствие ($&
) из предыдущего (s|||e
).
Если необходимо заменить каждым .
с a -
кроме последних 3 последних, с GNU sed
и принятие Вас имеет a rev
команда:
rev file | sed 's/\./-/4g' | rev
/r
работать).
– Joseph R.
29.01.2014, 01:33
Sed не является самым легким инструментом для задания — видят другие ответы для лучших инструментов — но он может быть сделан.
Заменять .
-
только до первого пространства, использовать s
в цикле.
sed -e '
: a # Label "a" for the branching command
s/^\([^ .]*\)\./\1-/ # If there is a "." before the first space, replace it by "-"
t a # If the s command matched, branch to a
'
(Обратите внимание, что некоторые sed реализации не поддерживают комментарии к той же строке. GNU sed делает.)
Вместо этого выполнить замену до последнего пространства:
sed -e '
: a # Label "a" for the branching command
s/\.\(.* \)/-\1/ # If there is a "." before the last space, replace it by "-"
t a # If the s command matched, branch to a
'
Другая техника использует пространство хранения sed. Сохраните бит, который Вы не хотите изменять в пространство хранения, делать Вашу работу, затем вспоминать пространство хранения. Здесь, я разделил строку в последнем пространстве и точках замены тире в первой части.
sed -e '
h # Save the current line to the hold space
s/.* / / # Remove everything up to the last space
x # Swap the work space with the hold space
s/[^ ]*$// # Remove everything after the last space
y/./-/ # Replace all "." by "-"
G # Append the content of the hold to the work space
s/\n// # Remove the newline introduced by G
'
Так как Rahul дал Вам канонический ответ для Вашего варианта использования, я думал, что попробую отвечать на номинальную проблему: замена всеми кроме последних x случаев regex:
perl -pe '
$count = tr{.}{.}; # Count '.' on the current line
$x = 3;
next LINE if $count <= $x;
while(s{\.}{-}){ # Substitute one '.' with a '-'
last if ++$i == $count - $x # Quit the loop before the last x substitutions
}
$i = 0
' your_file
Вышеупомянутый (протестированный) код не предполагает, что у Вас есть разделенные пробелом поля. Это заменит все точки на строке с тире кроме последних 3 точек. Замените 3
в коде к Вашей симпатии.
Можно использовать много различных инструментов для этого. Rahul Patil уже дал Вам a gawk
один, таким образом, вот немногие другие:
жемчуг
perl -lane '$F[0]=~s/\./-/g; print "@F"' file
-a
переключите жемчуг причин, чтобы автоматически разделить входные строки на пробеле и сохранить получающиеся поля в массив @F
. Первое поле, поэтому, будет $F[0]
таким образом, мы заменяем (s///
) все случаи .
с -
в первом поле и затем печатают целый массив.
оболочка
while read -r a b; do printf "%s %s\n" "${a//./-}" "$b"; done < file
Здесь, цикл с условием продолжения читает файл и автоматически разделяет на пробеле. Это создает два поля, $first
и $rest
. Конструкция ${first//pattern/replacement}
замены все случаи pattern
с replacement
.
perlrun(1)
скажет Вам это -a
"режим авторазделения", я предпочитаю думать о нем как"awk
режим" :D
– Joseph R.
28.01.2014, 17:50
Я полагаю, что это немного легче считать, чем большой противный regex. В основном я просто разделил строку на два поля в пробеле и использовании sed на первой части.
while read -r host ip; do
echo "$(sed 's/\./-/g' <<< "$host") $ip"
done < input_file
В зависимости от Вашей оболочки Вы могли также использовать $ {размещают//./-} вместо команды sed.
sed 's/\./-/' <file name>
без использования G
G
В конце команды вы можете сделать это ... Это просто заменит 1-е происхождение шаблона
awk
на основеnawk
, так все современныеawk
реализации должны иметьgsub
. На Солярисе Вам, возможно, понадобится/usr/xpg4/bin/awk
илиnawk
. – Stéphane Chazelas 28.01.2014, 17:46