LINUX.ORG.RU

sed: замена определенных символов встречающихся до некоторого знака

 , , , ,


1

1

Подскажите регулярку пж:

# Надо из 
aaa-bbb-ccc=aaa-bbb-ccc
# получить
aaa_bbb_ccc=aaa-bbb-ccc
Уточнение: надо чтобы работало для произвольных строк и меняло '-' (и другие символы, недопустимые в именах переменных bash) на '_', но только перед знаком '='

★★★★★

Последнее исправление: superuser (всего исправлений: 7)
{
	echo 'aaa-bbb-ccc=aaa-bbb-ccc'
	echo 'aaa-bbb-ccc'
} |
awk '
	/=/ {
		left = substr($0, 1, index($0, "=")-1)
		right = substr($0, index($0, "="))
		gsub(/-/, "_", left)
		print left right
	}
	!/=/ {print}
'

Тяжело, однако, живётся без sam, в котором идентичную операцию выполнит x/^[^=]*=/ x/-/ c/_/.

kaldeon
()
Ответ на: комментарий от legolegs

еще такая проблема всплыла. Если в regex указать несколько символов и указать -OFS==, то "-" меняет на «_» и после «=»

0 $ echo aaa-aaa-bbb-ccc.ddd=aaa-aaa.ddd | awk -F= -OFS== '{gsub(/[.-]/,"_",$1)}1'
aaa_aaa_bbb_ccc_ddd=aaa_aaa_ddd

superuser ★★★★★
() автор топика
$ echo -e 'a-b-c=d-e-f\nkuku-mumu=bebe-meme' | sed 'h; s/^[^=]*//; x; s/=.*$//; s/-/_/g; G; s/\n//'
a_b_c=d-e-f
kuku_mumu=bebe-meme


$ echo -e 'a-b.c=d.e-f\nkuku-mu.mu=bebe-me.me' | sed 'h; s/^[^=]*//; x; s/=.*$//; s/[.-]/_/g; G; s/\n//'
a_b_c=d.e-f
kuku_mu_mu=bebe-me.me
futurama ★★★★★
()
Последнее исправление: futurama (всего исправлений: 1)
Ответ на: комментарий от superuser

надо не -OFS==, а -vOFS==

Я ещё днём удивился, почему я не знаю такого ключа -OFS. А нет его. Получается FS='S==' и вся строка в $1.

Вот рабочий вариант:

$ echo aaa-aaa-bbb-ccc.ddd=aaa-aaa.ddd | awk -F= -vOFS== '{gsub(/[-.]/,"_",$1)}1'
aaa_aaa_bbb_ccc_ddd=aaa-aaa.ddd

PS в квадратных скобках - лучше ставить первым.

legolegs ★★★★★
()
Последнее исправление: legolegs (всего исправлений: 1)
Ответ на: комментарий от Aceler

Если уж предаваться нечестивым утехам….

mkfifo /tmp/aefdfhdfhha1 

tee >(cut -d '=' -f1 | tr '-' '_' > /tmp/aefdfhdfhha1 ) <<EOF | cut -d '=' -f2- | paste -d '=' /tmp/aefdfhdfhha1 -
aaa-bbb-ccc=aaa-bbb-ccc
aaa-aaa-bbb-ccc.ddd=aaa-aaa.ddd
a_b_c=d-e-f
kuku_mumu=bebe-meme
EOF
rm /tmp/aefdfhdfhha1 
 

(Синтаксически можно без фифо, но в любом случае лучше не обрабатывать потоки ромбом, иногда зависает.)

legolegs ★★★★★
()
Ответ на: комментарий от legolegs

Продолжу это мракобесие…

#include <stdio.h>

int main() {
    char buffer[256]; int found = 0; char c;
    while ((c = fgetc(stdin)) != EOF) {
        if (!found) {
            c = (c == '-') ? '_' : c;
            found = (c == '=');
        }
        putchar(c) ;
    }
    return 0;
}
$ cc test.c -o test
$ echo "aaa-aaa-bbb-ccc.ddd=aaa-aaa.ddd" | ./test
aaa_aaa_bbb_ccc.ddd=aaa-aaa.ddd
iron ★★★★★
()
$ echo aaa-bbb-ccc=aaa-bbb-ccc | sed -n 'h;s/=.*//;y/-/_/;x;s/[^=]*=//;H;x;y/\n/=/;p'
aaa_bbb_ccc=aaa-bbb-ccc
$ echo hello-world=hello-world | sed -n 'h;s/=.*//;y/-/_/;x;s/[^=]*=//;H;x;y/\n/=/;p'
hello_world=hello-world
$ 
i-rinat ★★★★★
()
Ответ на: комментарий от papin-aziat

Что-то сложно. Для единственной записи решение тривиально

function fixvarname() {
[ $# -ne 1 ] && return 1
local varname=${1%%=*}
local value=${1##*=}
varname=${varname//[-.]/_}
printf '%s' "${varname}=${value}"
}
$ fixvarname "aaa-AAA-b-ccc.ddd_xxx=aaa-aaa.ddd"
aaa_AAA_b_ccc_ddd_xxx=aaa-aaa.ddd

legolegs ★★★★★
()
Ответ на: комментарий от papin-aziat

и тебе патч

- var=aaa-bbb-ccc=aaa-bbb-ccc=aaa-bbb-ccc
+ var=aaa-bbb-ccc.ddd\&eee\$fff=111-222-333=444.555\&777\$888

- pre=${pre//-/_}
+ pre=${pre//[-.$&]/_}

superuser ★★★★★
() автор топика
Последнее исправление: superuser (всего исправлений: 2)
Ответ на: комментарий от superuser

Во, когда упрощаешь — надо быть внимательней к вариантам 😀

А посимвольный вариант работает неторопливо, но верно:

var='aaa-bbb-ccc.ddd&eee$fff=111-222-333=444.555&777$888'

for ((i=0; i<${#var}; ++i)); do
    [[ ${var:$i:1} == = ]] &&
        break
    [[ ${var:$i:1} == - ]] &&
        var=${var/-/_}
done

echo $var
aaa_bbb_ccc.ddd&eee$fff=111-222-333=444.555&777$888

😀

papin-aziat ★★★★★
()

понаписали тут портянки на sed...
Рулит bash:

$ while read var; do pre=${var%%=*}; pre=${pre//[-.$&]/_}; echo $pre=${var#*=}; done <<< 'aaa-bbb-ccc.ddd&eee$fff=111-222-333=444.555&777$888'
aaa_bbb_ccc_ddd_eee_fff=111-222-333=444.555&777$888

superuser ★★★★★
() автор топика
Последнее исправление: superuser (всего исправлений: 3)
Ответ на: комментарий от legolegs

Теперь бенчмарк надо пилить, раз уж сишечка вошла в тред

Так не вопрос)

C:

$ /usr/bin/time sh -c 'for i in $(seq 1 10000);do echo "aaa-aaa-bbb-ccc.ddd=aaa-aaa.ddd" | ./test > /dev/null
 ; done'
        26,11 real        10,64 user        20,72 sys

sed:

$ /usr/bin/time sh -c 'for i in $(seq 1 10000);do echo "aaa-aaa-bbb-ccc.ddd=aaa-aaa.ddd" | sed "h;s/.*=//;x;s/=.
*//;s/-/_/g;G;s/\n/=/" > /dev/null ; done'
        39,77 real        16,55 user        29,78 sys

perl:

$ /usr/bin/time sh -c 'for i in $(seq 1 10000);do echo "aaa-aaa-bbb-ccc.ddd=aaa-aaa.ddd" | perl -p -e "s/(?<!\=.{0,254})[-.]/_/g" > /dev/null ; done'
        46,93 real        24,43 user        26,71 sys
iron ★★★★★
()
Ответ на: комментарий от legolegs

Надо ещё вариант с массивом 🙂

var='aaa-bbb-ccc.ddd&eee$fff=111-222-333=444.555&777$888'

IFS== read -a array <<< $var
array[0]=${array[0]//-/_}
for i in ${array[@]}; do
    delimiter=${result:+=}
    result=${result}${delimiter}${i}
done

echo $result

Цикл ради известной идиомы (не сдержался) 😀

Так-то printf, да:

var='aaa-bbb-ccc.ddd&eee$fff=111-222-333=444.555&777$888'

IFS== read -a array <<< $var
array[0]=${array[0]//-/_}
result=$(printf %s= ${array[@]})

echo ${result%=}
papin-aziat ★★★★★
()
Последнее исправление: papin-aziat (всего исправлений: 2)
Ответ на: комментарий от superuser

Tool mindset vs perl mindset. Портянки на баше не особо лучше в читаемости и обслуживании.

Лучше всего здесь справился awk, мне кажется. Ещё лучше может sam, но это нераспространённый инструмент.

% echo 'aaa-bbb-ccc.ddd&eee$fff=111-222-333=444.555&777$888' |ssam -e 'x/^[^=]*=/ x/[\-.&$]/ c/_/'
aaa_bbb_ccc_ddd_eee_fff=111-222-333=444.555&777$888

(лучше, потому что меньше разношёрстных операций — нет отдельной особенной разбивки и склеивания, чисто поиск и замена по регулярному выражению)

kaldeon
()
Последнее исправление: kaldeon (всего исправлений: 1)
Ответ на: комментарий от legolegs

Как обезопасить спрашивающих уже этот чудесный скрипт?
https://github.com/void-linux/void-packages/pull/57292#issuecomment-3333666343

superuser ★★★★★
() автор топика
Последнее исправление: superuser (всего исправлений: 1)
Ответ на: комментарий от superuser

вместо eval нужно делать обычное присваивание

p=var
printf -v "$p" '%s' "any value"
echo "$var"

printf здесь выполняет роль $p='any value' (прям так нельзя написать в баше)

kaldeon
()
Последнее исправление: kaldeon (всего исправлений: 1)
Ответ на: комментарий от superuser

В общем скрипт выдает такую портянку

0 $ ./gen_crates.sh 
distfiles=
 https://crates.io/api/v1/crates/zerocopy/0.8.13/download>zerocopy-0.8.13.tar.gz
 https://crates.io/api/v1/crates/zerocopy-derive/0.8.13/download>zerocopy-derive-0.8.13.tar.gz
 https://crates.io/api/v1/crates/unicode-ident/1.0.12/download>unicode-ident-1.0.12.tar.gz
 https://crates.io/api/v1/crates/ucd-trie/0.1.6/download>ucd-trie-0.1.6.tar.gz
 https://crates.io/api/v1/crates/thiserror/2.0.11/download>thiserror-2.0.11.tar.gz
 https://crates.io/api/v1/crates/thiserror-impl/2.0.11/download>thiserror-impl-2.0.11.tar.gz
 https://crates.io/api/v1/crates/syn/2.0.87/download>syn-2.0.87.tar.gz
 https://crates.io/api/v1/crates/rustix/1.0.7/download>rustix-1.0.7.tar.gz
 https://crates.io/api/v1/crates/rustc-hash/2.1.1/download>rustc-hash-2.1.1.tar.gz
 https://crates.io/api/v1/crates/roxmltree/0.20.0/download>roxmltree-0.20.0.tar.gz
 https://crates.io/api/v1/crates/remain/0.2.12/download>remain-0.2.12.tar.gz
 https://crates.io/api/v1/crates/quote/1.0.35/download>quote-1.0.35.tar.gz
 https://crates.io/api/v1/crates/proc-macro2/1.0.86/download>proc-macro2-1.0.86.tar.gz
 https://crates.io/api/v1/crates/pest_meta/2.8.0/download>pest_meta-2.8.0.tar.gz
 https://crates.io/api/v1/crates/pest_generator/2.8.0/download>pest_generator-2.8.0.tar.gz
 https://crates.io/api/v1/crates/pest_derive/2.8.0/download>pest_derive-2.8.0.tar.gz
 https://crates.io/api/v1/crates/pest/2.8.0/download>pest-2.8.0.tar.gz
 https://crates.io/api/v1/crates/paste/1.0.14/download>paste-1.0.14.tar.gz
 https://crates.io/api/v1/crates/once_cell/1.8.0/download>once_cell-1.8.0.tar.gz
 https://crates.io/api/v1/crates/log/0.4.27/download>log-0.4.27.tar.gz
 https://crates.io/api/v1/crates/libc/0.2.168/download>libc-0.2.168.tar.gz
 https://crates.io/api/v1/crates/indexmap/2.2.6/download>indexmap-2.2.6.tar.gz
 https://crates.io/api/v1/crates/hashbrown/0.14.1/download>hashbrown-0.14.1.tar.gz
 https://crates.io/api/v1/crates/errno/0.3.12/download>errno-0.3.12.tar.gz
 https://crates.io/api/v1/crates/equivalent/1.0.1/download>equivalent-1.0.1.tar.gz
 https://crates.io/api/v1/crates/cfg-if/1.0.0/download>cfg-if-1.0.0.tar.gz
 https://crates.io/api/v1/crates/bitflags/2.9.1/download>bitflags-2.9.1.tar.gz
checksum=
 67914ab451f3bfd2e69e5e9d2ef3858484e7074d63f204fd166ec391b54de21d
 7988d73a4303ca289df03316bc490e934accf371af6bc745393cf3c2c5c4f25d
 3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b
 ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9
 d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc
 26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2
 25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d
 c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266
 357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d
 6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97
 1ad5e011230cad274d0532460c5ab69828ea47ae75681b42a841663efffaf794
 291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef
 5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77
 7f9f832470494906d1fca5329f8ab5791cc60beb230c74815dff541cbd2b5ca0
 db7d01726be8ab66ab32f9df467ae8b1148906685bbe75c82d1e65d7f5b3f841
 d725d9cfd79e87dccc9341a2ef39d1b6f6353d68c4b33c177febbe1a402c97c5
 198db74531d58c70a361c42201efde7e2591e976d518caf7662a47dc5720e7b6
 de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c
 692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56
 13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94
 5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d
 168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26
 7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12
 cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18
 5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5
 baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd
 1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967
skip_extraction=
 zerocopy-0.8.13.tar.gz
 zerocopy-derive-0.8.13.tar.gz
 unicode-ident-1.0.12.tar.gz
 ucd-trie-0.1.6.tar.gz
 thiserror-2.0.11.tar.gz
 thiserror-impl-2.0.11.tar.gz
 syn-2.0.87.tar.gz
 rustix-1.0.7.tar.gz
 rustc-hash-2.1.1.tar.gz
 roxmltree-0.20.0.tar.gz
 remain-0.2.12.tar.gz
 quote-1.0.35.tar.gz
 proc-macro2-1.0.86.tar.gz
 pest_meta-2.8.0.tar.gz
 pest_generator-2.8.0.tar.gz
 pest_derive-2.8.0.tar.gz
 pest-2.8.0.tar.gz
 paste-1.0.14.tar.gz
 once_cell-1.8.0.tar.gz
 log-0.4.27.tar.gz
 libc-0.2.168.tar.gz
 indexmap-2.2.6.tar.gz
 hashbrown-0.14.1.tar.gz
 errno-0.3.12.tar.gz
 equivalent-1.0.1.tar.gz
 cfg-if-1.0.0.tar.gz
 bitflags-2.9.1.tar.gz
post_extract()
	_prepare_subproject zerocopy 0.8.13
	_prepare_subproject zerocopy-derive 0.8.13
	_prepare_subproject unicode-ident 1.0.12
	_prepare_subproject ucd-trie 0.1.6
	_prepare_subproject thiserror 2.0.11
	_prepare_subproject thiserror-impl 2.0.11
	_prepare_subproject syn 2.0.87
	_prepare_subproject rustix 1.0.7
	_prepare_subproject rustc-hash 2.1.1
	_prepare_subproject roxmltree 0.20.0
	_prepare_subproject remain 0.2.12
	_prepare_subproject quote 1.0.35
	_prepare_subproject proc-macro2 1.0.86
	_prepare_subproject pest_meta 2.8.0
	_prepare_subproject pest_generator 2.8.0
	_prepare_subproject pest_derive 2.8.0
	_prepare_subproject pest 2.8.0
	_prepare_subproject paste 1.0.14
	_prepare_subproject once_cell 1.8.0
	_prepare_subproject log 0.4.27
	_prepare_subproject libc 0.2.168
	_prepare_subproject indexmap 2.2.6
	_prepare_subproject hashbrown 0.14.1
	_prepare_subproject errno 0.3.12
	_prepare_subproject equivalent 1.0.1
	_prepare_subproject cfg-if 1.0.0
	_prepare_subproject bitflags 2.9.1

superuser ★★★★★
() автор топика