вставить символ в позиции x, y, z в строке - PullRequest
1 голос
/ 10 марта 2019

Мне нужно вставить знак минуса "-" в строку ниже после 2 символов, а затем после 3 символов, например:

mystring="223334444"

и желаемый результат будет выглядеть так: 22-333-4444

Я могу вставить символы фиксированной длины, следуя приведенному ниже вопросу:

https://unix.stackexchange.com/questions/5980/how-do-i-insert-a-space-every-four-characters-in-a-long-line

, но в моем случае расщепление не является статическим (не после каждой n-й позициино после позиций x, y, z) мне нужно выражение для выполнения работы с использованием sed.

обновление Я могу получить требуемый формат с помощью нескольких команд sed, таких как: echo 111111111 | sed 's/.\{2\}/&-/' | sed 's/.\{6\}/&-/'

, но мне нужно знать, как мне этого добиться, используя одно выражение

Добавление дополнительной информации // Извините, что пропустил раньше

выходные данные 22-333-444 будут использоваться при некотором поиске (с использованием grep), и мне, возможно, придется выполнить тысячи таких преобразований, а затем выполнить поиск по выходным строкам, поэтому здесь также была бы желательна скорость / оптимизация обработки.

Добавление информации о поисковой детали в соответствии с запросом в комментариях

образец входного файла:

135311046
135310897
135311354
135310944
125312732
125222083
415211804
415222255
415204163
415206020

Я читаю этот файл построчно в некоторое времяв переменной line

я хочу преобразовать эту строку 135311046 в 13-531-1046 и затем выполнить grep для файла.

В настоящее время я использую нижеподстановка grep $(echo $line | sed 's/.\{2\}/&-/' | sed 's/.\{6\}/&-/') datafile.txt

файл данных содержит такие данные:

Line1.P2.ON28.C1.P1.FL1,12-522-2083
Line1.P1.ON19.C1.P1.FL1,12-522-2112
Line1.P1.ON34.C1.P1.FL1,12-530-2766
Line1.P2.ON15.C1.P1.FL1,12-531-1041
Line1.P2.ON15.C1.P3.FL1,12-531-1041
Line1.P2.ON15.C1.P4.FL1,12-531-1041
Line1.P1.ON39.C1.P1.FL1,12-531-1094
Line1.P2.ON26.C1.P1.FL1,12-531-2732
Line1.P1.ON57.C1.P1.FL1,12-533-4019

, поэтому мое основное требование - сделать преобразование в удобной / компактной форме, и так как это тысячи строк, мне нужнопоиск в другом файле, он должен быть быстрым / оптимизированным

Ответы [ 3 ]

3 голосов
/ 10 марта 2019

РЕДАКТИРОВАТЬ: Так как OP отредактировал сообщение с полным требованием, поэтому добавьте решение в соответствии с ним.

awk '
FNR==NR{
  a[substr($0,1,2)"-"substr($0,3,3)"-"substr($0,6)]
  next
}
($NF in a)'   Input_file1  FS=","  Input_file2

Это должно работать в любом awkПО МОЕМУ МНЕНИЮ.Вывод будет следующим:

Line1.P2.ON28.C1.P1.FL1,12-522-2083
Line1.P2.ON26.C1.P1.FL1,12-531-2732


1-е решение: Не могли бы вы попробовать следующее.Здесь я ставлю - после первых 2 символов, затем после 3 символов.Здесь я использую возможность sed сохранять значения в памяти, используя \(..\), что означает, что sed знает, что нужно сохранить первые 2 символа в памяти (к которым позже можно будет получить доступ, используя \ 1), аналогично, мы можем создатьбольше заполнителей памяти и могут получить к ним доступ позже по номерам при замене.

mystring="223334444"
echo "$mystring" | sed 's/\(..\)\(...\)\(....\)/\1-\2-\3/'

2-е решение: Или, если вы хотите заменить все 2 и все3 в значении строки (это не будет зависеть от места 2 и 3, он просто подставит их везде в строке), затем попробуйте выполнить следующее.

echo "$mystring" | sed -E 's/2+|3+/&-/g'

Вывод будет следующим.

22-333-4444
2 голосов
/ 10 марта 2019

Использование awk:

$ echo $mystring | awk 'BEGIN{FS=OFS=""}{$2=$2 "-";$5=$5 "-"}1'
22-333-4444

Объяснено:

awk 'BEGIN {
    FS=OFS=""   # field separators to null, ie. each char on an individual field
}{
    $2=$2 "-"   # set dashes to all the right places
    $5=$5 "-"
}1'             # output

Успешно протестировано на GNU awk, mawk, Busybox awk и BWK awk версии 20121220.

Обновление : я хочу преобразовать эту строку 135311046 в 13-531-1046 и затем выполнить grep для файла .Все в одной программе awk:

$ awk '
BEGIN {
    OFS=""
}
NR==FNR {
    $2=$2 "-";$5=$5 "-"
    a[$0]
    next
}
$NF in a' FS="" input FS="," data

Вывод:

Line1.P2.ON28.C1.P1.FL1,12-522-2083
Line1.P2.ON26.C1.P1.FL1,12-531-2732

Успешно протестировано на GNU awk, mawk и Busybox awk.Ошибка в BWK awk версии 20121220.

2 голосов
/ 10 марта 2019

В качестве альтернативы вы можете сделать это в bash без каких-либо регулярных выражений:

mystring="223334444"
echo "${mystring:0:2}-${mystring:2:3}-${mystring:5}"

22-333-4444
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...