o'ralgan birikma ifodasi va ta'qib qilish guruhi

Quyidagi satrlarni to'ldirish kerak:

start-pattern
[SYSTEM] capture ............................... FAIL [  2.825 s]
[SYSTEM] capture ............................... FAIL [  2.825 s]
[DEBUG] capture :: capture :: capture .......... FAIL [  0.866 s]
[DEBUG] capture :: me :: capture capture capture FAIL [  0.876 s]
[DEBUG] capture-me ............................. FAIL [  0.361 s]
end-pattern

[DEBUG] | [SYSTEM] va FAIL [. *] va oralig'i tashqari. > AND {start, end} -pattern matnini tanlang.

Yuqoridagi matn uchun chiqish quyidagilardan birini yoki bir nechtasidan iborat bo'lishi kerak:

capture
capture
capture::capture::capture
capture::me::capture capture capture
capture-me

Mana, men sinab ko'rdim, lekin barcha satrlarda ishlamaydi:

sed -e 's/\[DEBUG\] \(.*\) :: \(.*\) :: \(.*\) \([^.]FAIL \[.*\]) \[.*/\1::\2::\3::\4/' -e 's/\[SYSTEM\] \(.*\) \..*/\1/'
1
odatiy tartibda oddiy substitusiyalar uchun, ya'ni barchasi. Buni qilmoqchi bo'lgan narsa emas, shuning uchun bu sed uchun ish emas. Agar sed bilan bog'liq muammolarni hal qilishni talab qilyapsizmi?
qo'shib qo'ydi muallif Ed Morton, manba
Siz ... bo'shliqlar tashqari ... chiqishni xohlaganingizni aytasiz, ammo bo'shliqlarni o'z ichiga olgan chiqishni ko'rsatasiz. Matnni to'g'rilash yoki kutilgan natijalarni bir-biriga mos keladigan tarzda tuzatib qo'yish va ikkalasini ham ko'rsatish/aslida nima istayotganingizni ko'rsatish.
qo'shib qo'ydi muallif Ed Morton, manba
start-pattern va end-pattern kabi qanday ko'rinadi? ularning haqiqiy qadriyatlari qanday?
qo'shib qo'ydi muallif RomanPerekhrest, manba
to'liq kod sifatida start-pattern va end-pattern deb nomlanganmi?
qo'shib qo'ydi muallif RomanPerekhrest, manba
Savolga kichik o'zgarish kiritdingizmi, boshlang'ich va oxirgi naqshlar o'rtasidagi barcha satrlarni qayta ishlash kerak
qo'shib qo'ydi muallif askb, manba
Kechirasiz! Bu naqshlar emas, aniq kalit so'zlar
qo'shib qo'ydi muallif askb, manba
Ha, awk yoki boshqa narsa ham yaxshi bo'ladi.
qo'shib qo'ydi muallif askb, manba
Perl-one-liner ni qabul qila olmaysizmi? juda qisqa va oddiy
qo'shib qo'ydi muallif Shakiba Moshiri, manba

6 javoblar

Har qanday UNIX tizimida aniq, sodda, ishonchli, samarali va portativ ravishda so'ragan narsangizni qanday qilib bajarish kerak:

$ cat tst.awk
/start-pattern/ { inBlock=1 }
inBlock {
    if ( sub(/^\[(DEBUG|SYSTEM)\]/,"") && sub(/FAIL.*/,"") ) {
        gsub(/[[:space:].]/,"")
        print
    }
}
/end-pattern/ { inBlock=0 }

$ awk -f tst.awk file
capture
capture
capture::capture::capture
capture::me::capturecapturecapture
capture-me

Yuqoridagi "ta'qib qilish" lar orasida bo'sh joylar yo'qligi uchun bo'shliqlar va davrni tashqari chiqishni xohlaganingizni ayting. Agar haqiqatan ham istagan narsangiz faqatgina :: s atrofida bo'sh joylarni chiqarib yuborsa va chiqish chiziqlarining boshida/oxirida bu shunchaki tweak:

$ cat tst.awk
/start-pattern/ { inBlock=1 }
inBlock {
    if ( sub(/^\[(DEBUG|SYSTEM)\]/,"") && sub(/FAIL.*/,"") ) {
        gsub(/[[:space:]]*::[[:space:]]*/,"::")
        gsub(/^[[:space:]]+|[[:space:]]+$|[.]/,"")
        print
    }
}
/end-pattern/ { inBlock=0 }

$ awk -f tst.awk file
capture
capture
capture::capture::capture
capture::me::capture capture capture
capture-me
3
qo'shib qo'ydi
OK, men javob yozdim.
qo'shib qo'ydi muallif Ed Morton, manba
Uning qaysi qismi aniq emas?
qo'shib qo'ydi muallif Ed Morton, manba
Undan bo'sh joylarni chiqarib tashlash uchun so'ralgan narsa uchun o'yin. Men chop etilgan kutilgan natijani ishlab chiqaradigan versiyani qo'shib qo'ydim, buning o'rniga, bu haqiqatan ham istalgan va xato emas edi.
qo'shib qo'ydi muallif Ed Morton, manba
qo'shib qo'ydi muallif askb, manba
Ushbu savolga ham e'tibor qaratsangiz, men buni awk-da kim amalga oshirishi kerakligini tushunishni istayman: stackoverflow.com/questions/42434040/…
qo'shib qo'ydi muallif askb, manba
. Men chiqarib olishni xohlagan matn kerakli matndan emas.
qo'shib qo'ydi muallif askb, manba
Rahmat qilaman, ertaga uni sinab ko'rsata olasiz
qo'shib qo'ydi muallif askb, manba
Layn 4 - o'yin emas
qo'shib qo'ydi muallif askb, manba

Quyidagi sed buyruqlar kombinatsiyasini ishlating:

sed -En 's/^\[(DEBUG|SYSTEM)\] (.+) FAIL.*$/\2/p' testfile | sed -En 's/(\.|\s(::)\s)/\2/gp'

Chiqish:

capture 
capture 
capture::capture::capture 
capture::me::capture capture capture
capture-me 

s/(\. | \ S (::) \ s)/\ 2/gp ikkinchi buyrug'i hamma nuqtalarni . olib tashlaydi va ':: "" trimmed qiymati bilan ::


Qisqartirilgan versiya shunday ko'rinadi:

sed -En 's/^\[(DEBUG|SYSTEM)\] (.+) FAIL.*$/\2/;s/(\.|\s(::)\s)/\2/gp' testfile
1
qo'shib qo'ydi
Savolga kichik o'zgarish kiritdingizmi, boshlang'ich va oxirgi naqshlar o'rtasidagi barcha satrlarni qayta ishlash kerak
qo'shib qo'ydi muallif askb, manba
awk -F'[]F]' '{gsub(/\./,"")gsub(/ /,"")gsub(/ec/,"e c");print $2}' file

capture
capture
capture::capture::capture
capture::me::capture capture capture
capture-me
1
qo'shib qo'ydi
Rahmat, men buni o'tkazib yubordim.
qo'shib qo'ydi muallif Claes Wikner, manba

Siz quyidagilarni foydalanishingiz mumkin:

$ gsed -nE 's/\[(DEBUG|SYSTEM)\] (.*) FAIL.*/\2/;{s/[.]//g;s/ :: /::/g;p;}' file                                                                                                                                                            
capture 
capture 
capture::capture::capture 
capture::me::capture capture capture
capture-me 

-n parametri avtomatik ravishda sed bosib chiqarishni to'xtatadi va -E kengaytirilgan muntazam ifodalarni o'zgartiradi (bu parametr bilan -r GNU sed, ammo -E GNU va BSD bilan ham ishlaydi) .

s              # Substitution command
/              # Start of match
\[             # Match a literal [
(DEBUG|SYSTEM) # Match DEBUG OR SYSTEM
\]             # Match a literal ] followed by a space
(.*)           # Match everything after and capture it
 FAIL.*        # Match a FAIL and everything after
/              # Stop match and start replacement
\2             # Replace with the second capture group
{              # If substitution matched applied following commands
s/[.]//g;      # Global substitution of literal .
s/ :: /::/g;   # Global substitution of spaces around literal ::
p;             # Print the result
}   
1
qo'shib qo'ydi
@askb faqat namunaviy kiritishda ishga tushirishi mumkin va xatoga yo'l qo'ysangiz, menga xabar bering. Linuxda GNU-da ishlayotganini ko'ring. ideone.com/SmQSqo
qo'shib qo'ydi muallif Chris Seymour, manba
@askb satr [DEBUG] bilan boshlanadi yoki oldin bo'sh joy bormi?
qo'shib qo'ydi muallif Chris Seymour, manba
@askb yangilangan buyruqni sinab ko'ring, siz talab qilgan chiqimni ishlab chiqarishi kerak.
qo'shib qo'ydi muallif Chris Seymour, manba
@MarkReed qachon kiritilganiga ishonchim komil emas, lekin xotirani eslab qolishim uchun hujjatlashtirilgan qo'llab-quvvatlanadigan variant.
qo'shib qo'ydi muallif Chris Seymour, manba
Savolga kichik o'zgarish kiritdingizmi, boshlang'ich va oxirgi naqshlar o'rtasidagi barcha satrlarni qayta ishlash kerak
qo'shib qo'ydi muallif askb, manba
Afsuski men foydalanadigan xatolik bilan, yoki -n yoki -E
qo'shib qo'ydi muallif askb, manba

Bu men uchun namuna kiritishda ishlaydi:

sed -nE '/^.*\[(SYSTEM|DEBUG)\] *(.*[^ ]) *FAIL.*$/{;s//\2/;s/[.]//g;p;}'
  1. -n says "Don't print every line"
  2. -E turns on extended regular expressions (required for alternation with |; without it, not available even as \|)
  3. /^.*\[(SYSTEM|DEBUG)\] *(.*[^ ]) *FAIL.*$/ matches all of each line we're looking for
  4. { begins a block of semicolon-separated commands to apply to matching lines
  5. s//\2/ says to replace whatever matched the previous regex with just the part that matched between the second set of (...)
  6. s/[.]//g deletes all periods.
  7. p prints out the line
  8. } terminates the block.
1
qo'shib qo'ydi
Savolga kichik o'zgarish kiritdingizmi, boshlang'ich va oxirgi naqshlar o'rtasidagi barcha satrlarni qayta ishlash kerak
qo'shib qo'ydi muallif askb, manba
capture :: me :: capturecapturecapture tashqari barcha qatorlarni to'g'ri ishlashi capture :: me :: capture capture capture
qo'shib qo'ydi muallif askb, manba
Shunday qilib ichki bo'sh joylarini saqlashni xohlaysiz. Tahrirlangan javobni tekshiring.
qo'shib qo'ydi muallif Mark Reed, manba

Bu ham ishni qiladi:

sed -n -e '/^\[SYSTEM\]/ ba; /^\[DEBUG\]/ ba; b;'
       -e ':a s/^\[.*\]\(.*\)FAIL.*/\1/; s/[ \.]*//g; \
           :c s/\(capture\)\(capture\)/\1 \2/g; tc; p;'
testcases.txt

Chiqish ma'lumotlari:

capture
capture
capture::capture::capture
capture::me::capture capture capture
capture-me

Agar chiziq [SYSTEM] yoki [DEBUG] bilan boshlangan bo'lsa, filial olinadi va o'zgarish bajariladi va natija chiqariladi. Aks holda hech narsa qilinmaydi.

Va bu talab (chunki bu muammoning tavsifida eslatilmadi, lekin umuman so'ragan chiqishi bilan ifodalanadi). Bo'shliqlarni ketma-ket ikkita qo'lga kiritishda ushlab turuvchi yana bir qurilma mavjud.

Batafsilroq:

1) -n : Agar p buyrug'i bilan aniq majburlanmagan bo'lsa, naqsh maydonini chop etma.

2.) ba : a yorliqlariga o'tish uchun o'tish.

3.) b : skript oxiriga o'tish.

4. tc : t oxirgi marta ishlatilganligi va o'qilganidan beri muvaffaqiyatli o`zgarishlar amalga oshirilsa c , T ).

1
qo'shib qo'ydi