Faqat 2d qatorlarni topish va matnni almashtirish uchun sed/perlni qanday ishlatish kerak?

Hozirda shunga o'xshash kodlarim bor:

static double    testVar1          [2][8]  = {0.0}    ;  /* This is for testing var 1 */
static double    var_test2         [3][2]  = {0.0}    ;  /* This is for testing var 2 */
static double    var_test3         [4]     = {0.0}    ;  /* This is for testing var 3 */

C ++ dagi 2d qatorlari juftlikdan burilmagan kvadratchalar bilan ishga tushirilsin, shuning uchun faqat 2d qatorlarini topib, uni shunday o'zgartirish kerak:

static double    testVar1          [2][8]  = {{0.0}}  ;  /* This is for testing var 1 */
static double    var_test2         [3][2]  = {{0.0}}  ;  /* This is for testing var 2 */
static double    var_test3         [4]     = {0.0}    ;  /* This is for testing var 3 */

Men guruhlarni ishlatish uchun sed bilan ishlayapman, lekin braxenlardan qochish uchun qanday qilib qochish kerakligini tushunolmayapman, ayrim xabarlar qochib ketmaslikni taklif qiladi. Men ham muntazam muntazam ifodalarsiz harakat qildim.

Hozirgi kunda faqat 9 guruhni topish mumkinligini bilib oldim. Har qanday taklif bormi?

sed -i -r 's/(.*)(\[)([0-9]+)(\])(\[)([0-9]+)(\])(.*)(\{)(0.0)(\})(.*)/echo "\1\2\3"/ge'
2

6 javoblar

Perl skriptini quyidagi regex bilan ishlating:

\w+\s*(?:\[\d+\]){2}\s*=\s*\K\{([\d.]*)\}

Buni \ {\ {\ 1 \} \} bilan almashtiring. Qarang: regex101.com ustida demo .


Broken down, this says:
\w+            # at least one word character
\s*            # Zero or more spaces
(?:\[\d+\]){2} # [0][1] or any other two-dimensional array
\s*=\s*        # spaces = and spaces
\K             # "forget" everything
\{([\d.]*)\}   # match and capture {number}
2
qo'shib qo'ydi

2u va 1e-06l (va hokazo) kabi tovarlarga nisbatan ehtiyotkorlik bilan Perl bitta lineri,

perl -pe's/(?:\[ [^]]+ \]){2} \s*=\s* \K (\{ [^}]+ \})/{$1}/x' in > out

[n] [[]] uchun (?:) guruhlari (ta'qib qilinmasdan) va (?: \ [[]]] + m] . \ K , "Http://perldoc.perl.org/perlretut.html#Looking-ahead-and-looking-behind" rel = "nofollow noreferrer"> positive lookbehind , bu ham avvalgi o'yinlarni qoldiradi, shuning uchun ularni qaytarib olish kerak.

[] ichidagi tamsayı bilan oddiygina raqamlar va n} da n.m da joylashgan float bilan bu soddalashtiriladi

perl -pe's/(?:\[\d+\]){2}\s*=\s*\K( \{[\d.]+\} )/{$1}/x' in > out

[\ d.] , .2..3 kabi har qanday noto'g'ri narsalarga ruxsat berishini unutmang, lekin bu boshqa masala.


Biroq, vec [1.2e + 01] bilan bir qatorda indekslar kabi yaxshi kodlar kabi 2u (son bilan) kabi raqamlar uchun litals foydalanish uchun ehtiyot bo'ling yoki hatto vec [1.2] . Float/er-xotin harflar uchun turli xil belgilar ham ma'lumotlarda ko'rsatilish ehtimoli ko'proq. Umuman men shunga o'xshash dumaloq naqsh bilan borardim

perl -pe's/(?:\[ [\d\w+-.]+ \]){2}\s*=\s*\K(\{ [\d\w+-.]+ \})/{$1}/x' in > out

Shuni yodda tutingki, bu turli xil noto'g'ri formatlarga ruxsat beradi va shuning uchun ma'lumotlarni yaxshi tekshirmaydi.

2
qo'shib qo'ydi
@DmitryEgorov Rahmat, yaxshi nuqta. Ehtimol, bu juda qulay.
qo'shib qo'ydi muallif zdim, manba
Va "tonna kodlar" mavjud ekan, in-lyderni tahrirlash (-i) bizning holatlarda qulay bo'lishi mumkin.
qo'shib qo'ydi muallif Dmitry Egorov, manba

Bu erda regex kırışıklıkları bilan ütülenen sed tashabbusi bilan.

sed -i -r 's/(.*\[[0-9]+\]\[[0-9]+\].*)(\{0.0\})(.*)/\1{\2}\3/'

Katta miqdordagi qo'shimcha guruhlangan parantezlar mavjud edi, shuning uchun \ 1 \ 2 \ 3 faqat o'yinning eng boshlanishini bildiradi. Men ularni tashqariga olib chiqdim. Yodda tutingki, qo'lga kiritishlar chapdan o'ngga, shuning uchun birinchi chap burchakda \ 1 guruhini yaratadi, ikkinchisi \ 2 va hokazolarni yozadi.

GNU sed kengaytmasi /e siz qobiqni zaxira dizgisida chaqirishga imkon beradi, ammo bu holda bu qiymat qo'shilmagan va muhim qo'shimcha xatolar kiritilgan, shuning uchun uni qabul qilish no-brainer. /g variantida har bir satrda bir nechta mos kelishi kutilsa, mantiqiy bo'ladi, lekin sizning misolingiz bir nechta mos keladigan kirish qatorlari misollarini ko'rsatmaydi va barcha skriptni qo'llab-quvvatlash uchun ancha murakkab bo'lishi kerak shuning uchun men buni ham olib tashladim.

Depending on the language you are attempting to process and the regularity of the files, you might want to permit whitespace between the closing and opening square brackets, or not; and the "anything" wildcard between the closing square bracket and the opening curly bracket looks somewhat prone to false positives (matching where you don't want it to) -- maybe change it to only permit whitespace and and equals sign, like [ =]* instead of .*

1
qo'shib qo'ydi
Rahmat!! Buyuk tushuntirishlar va men boshqa sed buyruqlarini keraksiz variantlar bilan tozaladim. Bu buyruq men uchun ishlagan va men uni ehtiyojlarimga mos ravishda bir oz o'zgartirdim. Ha, men sizning misolingizni ko'rganingizdan keyin juda ko'p keraksiz guruhlar bor edi, tushunish juda oson. Yana bir bor rahmat!
qo'shib qo'ydi muallif bobbay, manba

Sed bilan boshqa yondashuv:

sed -i -r 's/((\[[0-9]\]){2} *= )(\{[^}]*\})/\1{\3}/' file

BRE rejimida bir xil bo'ladi:

sed -i 's/\(\(\[[0-9]\]\)\{2\} *= \({[^}]*}\)\)/\1{\2}/' file
1
qo'shib qo'ydi
sed -i '/]\[/s/[{}]/&&/g' file
1
qo'shib qo'ydi
qo'shib qo'ydi muallif Toby Speight, manba
sed -i '/]\[/s/[{}]/&&/g' file
1
qo'shib qo'ydi
qo'shib qo'ydi muallif Toby Speight, manba