10 գործնական Grep հրամանի օրինակներ մշակողների համար


grep հրամանն օգտագործվում է ֆայլերում օրինաչափություններ գտնելու համար: Այս ձեռնարկը ցույց է տալիս grep հրամանի ամենատարածված օրինակներից մի քանիսը, որոնք հատկապես օգտակար կլինեն ծրագրային ապահովման մշակողների համար:

Վերջերս ես սկսեցի աշխատել Asciidoctor.js-ի և վրա Asciidoctor.js-pug և Asciidoctor-կաղապարների վրա: js նախագիծ.

Միշտ չէ, որ հեշտ է անմիջապես արդյունավետ լինել, երբ առաջին անգամ փորփրում ես մի քանի հազար տող պարունակող կոդերի բազան: Բայց իմ գաղտնի զենքը՝ այսքան կոդի տողերի միջով իմ ճանապարհը գտնելու համար, grep գործիքն է:

Ես պատրաստվում եմ ձեզ հետ կիսվել, թե ինչպես օգտագործել grep հրամանը Linux-ում օրինակներով:

Linux-ում grep հրամանների իրական կյանքում օգտակար օրինակներ

Եթե նայեք man-ին, կտեսնեք grep գործիքի կարճ նկարագրությունը. «

Այնուամենայնիվ, մի խաբվեք նման խոնարհ սահմանմանը. grep-ը Unix գործիքների տուփի ամենաօգտակար գործիքներից մեկն է, և կան անհամար առիթներ այն օգտագործելու հենց տեքստային ֆայլերի հետ աշխատելուն պես:

Միշտ ավելի լավ է ունենալ իրական աշխարհի օրինակներ՝ իմանալու համար, թե ինչպես են ամեն ինչ աշխատում: Այսպիսով, ես կօգտագործեմ Asciidoctor.js սկզբնաղբյուր ծառը` պատկերացնելու համար grep որոշ հնարավորություններ:

Դուք կարող եք ներբեռնել այդ աղբյուրի ծառը GitHub-ից, և եթե ցանկանում եք, կարող եք նույնիսկ ստուգել նույն փոփոխությունները, որոնք ես օգտագործել եմ այս հոդվածը գրելիս: Դա թույլ կտա ձեզ ստանալ արդյունքներ, որոնք լիովին նույնական են այս հոդվածի մնացած հատվածում նկարագրվածներին.

git clone https://github.com/asciidoctor/asciidoctor.js
cd asciidoctor.js
git checkout v1.5.6-rc.1

1. Գտեք տողի բոլոր երևույթները (հիմնական օգտագործում)

Asciidoctor.js-ն աջակցում է Nashorn JavaScript շարժիչը Java պլատֆորմի համար: Ես չգիտեմ Nashorn-ը, ուստի կարող եմ օգտվել այդ հնարավորությունից և ավելին իմանալ դրա մասին՝ ուսումնասիրելով նախագծի մասերը, որոնք հղում են կատարում JavaScript շարժիչին:

Որպես ելակետ՝ ես ստուգեցի, արդյոք կա՞ն Nashorn-ի հետ կապված որոշ կարգավորումներ package.json ֆայլում, որոնք նկարագրում են նախագծի կախվածությունները.

linux@handbook:~$ grep nashorn package.json
    "test": "node npm/test/builder.js && node npm/test/unsupported-features.js && node npm/test/jasmine-browser.js && node npm/test/jasmine-browser-min.js && node npm/test/jasmine-node.js && node npm/test/jasmine-webpack.js && npm run test:karmaBrowserify && npm run test:karmaRequirejs && node npm/test/nashorn.js",

Այո, ըստ երեւույթին, եղել են Նաշորնին հատուկ թեստեր: Այսպիսով, եկեք ուսումնասիրենք դա մի փոքր ավելին:

2. Գործերի անզգայուն որոնում ֆայլերի հավաքածուում

Այժմ ես ուզում եմ ավելի մոտիկից նայել ./npm/test/ գրացուցակի ֆայլերին, որտեղ բացահայտորեն նշվում է Nashorn-ը:

Մեծատառերի անզգույշ որոնումը (-i տարբերակ) հավանաբար ավելի լավ է այստեղ, քանի որ ես պետք է գտնեմ nashorn և Nashorn (կամ որևէ այլ) հղումները։ մեծ և փոքրատառ նիշերի համադրություն).

linux@handbook:~$ grep -i nashorn npm/test/*.js
npm/test/nashorn.js:const nashornModule = require('../module/nashorn');
npm/test/nashorn.js:log.task('Nashorn');
npm/test/nashorn.js:nashornModule.nashornRun('jdk1.8.0');

Իրոք, գործի անզգայունությունն այստեղ օգտակար էր։ Հակառակ դեպքում, ես բաց կթողնեի require('../module/nashorn') հայտարարությունը: Անկասկած, ես պետք է ավելի ուշ ուսումնասիրեմ այդ ֆայլը ավելի մանրամասն:

3. Գտեք բոլոր չհամապատասխանող ֆայլերը

Ի դեպ, npm/test/ գրացուցակում կա՞ն ոչ Nashorm-ի հատուկ ֆայլեր: Այս հարցին պատասխանելու համար մենք կարող ենք օգտագործել grep-ի «տպել չհամապատասխանող ֆայլեր» տարբերակը (-L տարբերակ):

sh$ grep -iL nashorn npm/test/*
npm/test/builder.js
npm/test/jasmine-browser-min.js
npm/test/jasmine-browser.js
npm/test/jasmine-node.js
npm/test/jasmine-webpack.js
npm/test/unsupported-features.js

Ուշադրություն դարձրեք, թե ինչպես է -L տարբերակով փոխվել grep-ի ելքը՝ ցուցադրելով միայն ֆայլերի անունները: Այսպիսով, վերը նշված ֆայլերից և ոչ մեկը չի պարունակում «նաշորն» տողը (անկախ դեպքից): Դա չի նշանակում, որ դրանք ինչ-որ կերպ կապված չեն այդ տեխնոլոգիայի հետ, բայց համենայնդեպս, «n-a-s-h-o-r-n» տառերը չկան:

4. Գտեք օրինաչափություններ թաքնված ֆայլերում և ռեկուրսիվ կերպով ենթագրքերում

Վերջին երկու հրամաններն օգտագործում էին shell glob օրինաչափություն՝ ստուգման ենթակա ֆայլերի ցանկը grep հրամանին փոխանցելու համար:

Այնուամենայնիվ, սա ունի որոշ բնորոշ սահմանափակումներ. աստղը (*) չի համընկնի թաքնված ֆայլերի հետ: Ոչ էլ այն չի համընկնի ենթատեղեկատուներում պարունակվող ֆայլերի հետ (ի վերջո):

Լուծումը կլինի grep-ը համատեղել find հրամանի հետ՝ չհիմնվելով shell glob օրինաչափության վրա.

# This is not efficient as it will spawn a new grep process for each file
linux@handbook:~$ find npm/test/ -type f -exec grep -iL nashorn \{} \;
# This may have issues with filenames containing space-like characters
linux@handbook:~$ grep -iL nashorn $(find npm/test/ -type f)

Ինչպես նշեցի վերը նշված կոդի բլոկի մեկնաբանություններում, յուրաքանչյուր լուծում ունի թերություններ:

Ինչ վերաբերում է տարածության նման նիշեր պարունակող ֆայլերի անուններին, ես թույլ եմ տալիս ուսումնասիրել grep -z տարբերակը, որը համակցված է find հրամանի -print0 տարբերակի հետ: , կարող է մեղմել այդ խնդիրը։ Մի հապաղեք օգտագործել այս հոդվածի վերջում գտնվող մեկնաբանությունների բաժինը՝ այդ թեմայի վերաբերյալ ձեր գաղափարները կիսելու համար:

Այնուամենայնիվ, ավելի լավ լուծումը կօգտագործի grep-ի «ռեկուրսիվ» տարբերակը: Այդ տարբերակով դուք հրամանի տողում տալիս եք ձեր որոնման ծառի արմատը (սկզբնական գրացուցակը) ուսումնասիրման ենթակա ֆայլերի անունների բացահայտ ցանկի փոխարեն:

-r ընտրանքով grep-ը կփնտրի նշված գրացուցակի բոլոր ֆայլերը, ներառյալ թաքնվածները, և այնուհետև այն ռեկուրսիվորեն կիջնի ցանկացած ենթացանց.

linux@handbook:~$ grep -irL nashorn npm/test/npm/
npm/test/builder.js
npm/test/jasmine-browser-min.js
npm/test/jasmine-browser.js
npm/test/jasmine-node.js
npm/test/jasmine-webpack.js
npm/test/unsupported-features.js

Իրականում, այդ տարբերակով ես կարող եմ նաև սկսել իմ ուսումնասիրությունը մեկ մակարդակից վեր՝ տեսնելու, որ կան ոչ npm թեստեր, որոնք նույնպես ուղղված են Nashorn-ին.

linux@handbook:~$ grep -irL nashorn npm/

Ես թույլ եմ տալիս, որ դուք ինքներդ փորձարկեք այդ հրամանը՝ դրա արդյունքը տեսնելու համար. բայց որպես հուշում կարող եմ ասել, որ դուք պետք է գտնեք ավելի շատ համապատասխան ֆայլեր:

5. Ֆայլերի զտում իրենց անունով (օգտագործելով կանոնավոր արտահայտություններ)

Այսպիսով, թվում է, թե այդ նախագծում կան Nashorn-ի հատուկ թեստեր: Քանի որ Nashorn-ը Java-ն է, մեկ այլ հարց, որը կարող է առաջանալ, կլինի «Արդյո՞ք նախագծում կա Java աղբյուրի որոշ ֆայլեր, որոնք բացահայտորեն նշում են Nashorn-ը: «.

Կախված ձեր օգտագործած grep տարբերակից, այդ հարցին պատասխանելու առնվազն երկու լուծում կա:

Առաջինն այն է, որ օգտագործենք grep՝ գտնելու բոլոր ֆայլերը, որոնք պարունակում են «nashorn» օրինաչափությունը, այնուհետև այդ առաջին հրամանի ելքը տեղափոխել երկրորդ grep օրինակ, որը զտում է ոչ Java-ն: աղբյուր ֆայլեր:

linux@handbook:~$ grep -ir nashorn ./ | grep "^[^:]*\.java"
./spec/nashorn/AsciidoctorConvertWithNashorn.java:public class AsciidoctorConvertWithNashorn {
./spec/nashorn/AsciidoctorConvertWithNashorn.java:    ScriptEngine engine = engineManager.getEngineByName("nashorn");
./spec/nashorn/AsciidoctorConvertWithNashorn.java:    engine.eval(new FileReader("./spec/nashorn/asciidoctor-convert.js"));
./spec/nashorn/BasicJavascriptWithNashorn.java:public class BasicJavascriptWithNashorn {
./spec/nashorn/BasicJavascriptWithNashorn.java:    ScriptEngine engine = engineManager.getEngineByName("nashorn");
./spec/nashorn/BasicJavascriptWithNashorn.java:    engine.eval(new FileReader("./spec/nashorn/basic.js"));

Հրամանի առաջին կեսը պետք է հասկանալի լինի մինչ այժմ։ Իսկ ի՞նչ կասեք այդ «^[\^:]*\\.java» մասի մասին։

Եթե չնշեք -F տարբերակը, grep ենթադրում է, որ որոնման օրինաչափությունը կանոնավոր արտահայտություն է: Դա նշանակում է, որ բացի պարզ նիշերից, որոնք բառացիորեն կհամապատասխանեն, դուք մուտք ունեք մետանիշերի մի շարք՝ ավելի բարդ օրինաչափություններ նկարագրելու համար: Վերևում օգտագործած օրինաչափությունը կհամապատասխանի միայն.

  • ^ տողի սկիզբը

  • [^:]* որին հաջորդում է ցանկացած նիշի հաջորդականություն, բացի երկու կետից

  • \., որին հաջորդում է կետը (կետը հատուկ նշանակություն ունի regex-ում, այնպես որ ես պետք է պաշտպանեի այն հետշեղով` արտահայտելու իմ ուզածը: բառացի համընկնում)

  • java և հաջորդում են չորս տառերը «java. »

Գործնականում, քանի որ grep-ը կօգտագործի երկու կետ՝ ֆայլի անվանումը կոնտեքստից առանձնացնելու համար, ես ֆայլի անվան բաժնում պահում եմ միայն .java ունեցող տողերը: Արժե նշել, որ կ կհամընկնի նաև .javascript ֆայլերի անուններին: Սա մի բան է, որը ես թույլ եմ տալիս փորձել ինքնուրույն լուծել, եթե ուզում ես:

6. Ֆայլերի զտում իրենց անունով՝ օգտագործելով grep

Կանոնավոր արտահայտությունները չափազանց հզոր են: Սակայն կոնկրետ այդ դեպքում դա չափազանցված է թվում։ Չհիշատակելով վերը նշված լուծումը, մենք ժամանակ ենք ծախսում բոլոր ֆայլերի ուսումնասիրության վրա՝ փնտրելով «nashorn» օրինակը. արդյունքների մեծ մասը անտեսվում է խողովակաշարի երկրորդ քայլից:

Եթե դուք օգտագործում եք grep-ի GNU տարբերակը, ինչը հավանական է, եթե դուք օգտագործում եք Linux, դուք ունեք մեկ այլ լուծում, թեև --include տարբերակով: Սա հրահանգում է grep-ին որոնել միայն այն ֆայլերում, որոնց անվանումը համապատասխանում է տվյալ գլոբային օրինաչափությանը.

linux@handbook:~$ grep -ir nashorn ./ --include='*.java'
./spec/nashorn/AsciidoctorConvertWithNashorn.java:public class AsciidoctorConvertWithNashorn {
./spec/nashorn/AsciidoctorConvertWithNashorn.java:    ScriptEngine engine = engineManager.getEngineByName("nashorn");
./spec/nashorn/AsciidoctorConvertWithNashorn.java:    engine.eval(new FileReader("./spec/nashorn/asciidoctor-convert.js"));
./spec/nashorn/BasicJavascriptWithNashorn.java:public class BasicJavascriptWithNashorn {
./spec/nashorn/BasicJavascriptWithNashorn.java:    ScriptEngine engine = engineManager.getEngineByName("nashorn");
./spec/nashorn/BasicJavascriptWithNashorn.java:    engine.eval(new FileReader("./spec/nashorn/basic.js"));

7. Բառեր գտնելը

Asciidoctor.js նախագծի հետաքրքիրն այն է, որ այն բազմալեզու նախագիծ է: Asciidoctor-ն իր հիմքում գրված է Ruby-ով, ուստի JavaScript-ի աշխարհում օգտագործելի լինելու համար այն պետք է «փոխադրվի»՝ օգտագործելով Opal-ը՝ Ruby-ից JavaScript աղբյուր-աղբյուր կոմպիլյատոր: Մեկ այլ տեխնոլոգիա, որի մասին նախկինում չգիտեի։

Այսպիսով, Nashorn-ի առանձնահատկությունները ուսումնասիրելուց հետո ես ինձ հանձնարարեցի Opal API-ն ավելի լավ հասկանալու խնդիր: Որպես այդ որոնման առաջին քայլ, ես փնտրեցի Opal գլոբալ օբյեկտի բոլոր հիշատակումները նախագծի JavaScript ֆայլերում: Այն կարող է հայտնվել ազդեցություններում (Opal =), անդամի մուտքի (Opal.) կամ գուցե նույնիսկ այլ համատեքստերում: Կանոնավոր արտահայտությունը կհաջողվեր: Այնուամենայնիվ, ևս մեկ անգամ, grep-ն ունի ավելի թեթև լուծում այդ ընդհանուր օգտագործման դեպքը լուծելու համար: Օգտագործելով -w տարբերակը, այն կհամապատասխանի միայն բառերին, այսինքն՝ նախշերին, որոնց նախորդում և հաջորդում է ոչ բառային նիշը: Ոչ բառային նիշը կա՛մ տողի սկիզբն է, կա՛մ տողի վերջը, կա՛մ ցանկացած նիշ, որը ոչ տառ է, ոչ թվանշան, ոչ էլ ընդգծված:

linux@handbook:~$ grep -irw --include='*.js' Opal .
...

8. ելքի գունավորում

Ես չեմ պատճենել նախորդ հրամանի արդյունքը, քանի որ կան շատ համընկնումներ: Երբ արդյունքը նման խիտ է, դուք կարող եք մի փոքր գույն ավելացնել՝ հասկանալու համար: Եթե սա արդեն իսկ կազմաձևված չէ ձեր համակարգում լռելյայնորեն, կարող եք ակտիվացնել այդ հատկությունը՝ օգտագործելով GNU --color տարբերակը:

linux@handbook:~$ grep -irw --color=auto --include='*.js' Opal .
...

Դուք պետք է ստանաք նույն երկար արդյունքը, ինչ նախկինում, բայց այս անգամ որոնման տողը պետք է երևա գունավոր, եթե դա դեռ այդպես չէ:

9. Համապատասխան տողերի կամ համընկնող ֆայլերի հաշվում

Ես կրկնակի նշեցի, որ նախորդ հրամանների արդյունքը շատ երկար էր: Կոնկրետ ինչքա՞ն ժամանակ։

linux@handbook:~$ grep -irw --include='*.js' Opal . | wc -l
86

Դա նշանակում է, որ մենք ունենք ընդհանուր 86 համընկնող տող բոլոր ուսումնասիրված ֆայլերում: Այնուամենայնիվ, քանի՞ տարբեր ֆայլեր են համընկնում: -l տարբերակով դուք կարող եք սահմանափակել grep ելքը համապատասխան ֆայլերը՝ համապատասխան < ցուցադրելու փոխարեն:գծեր: Այսպիսով, այդ պարզ փոփոխությունը ցույց կտա, թե քանի ֆայլ են համընկնում.

linux@handbook:~$ grep -irwl --include='*.js' Opal . | wc -l
20

Եթե դա ձեզ հիշեցնում է -L տարբերակը, զարմանալի չէ. քանի որ այն համեմատաբար տարածված է, փոքրատառերը/մեծատառերը օգտագործվում են լրացուցիչ տարբերակները տարբերելու համար: -l ցուցադրում է համապատասխան ֆայլերի անունները: -L ցուցադրում է չհամապատասխանող ֆայլերի անուններ: Մեկ այլ օրինակի համար ես թույլ եմ տալիս ստուգել ձեռնարկը -h/-H տարբերակների համար:

Եկեք փակենք այդ փակագիծը և վերադառնանք մեր արդյունքներին՝ 86 համապատասխանող տող: 20 համապատասխանող ֆայլեր: Այնուամենայնիվ, ինչպե՞ս են բաշխվում համապատասխան գծերը համապատասխան ֆայլերում: Մենք կարող ենք իմանալ, որ օգտագործելով -c տարբերակը grep, որը կհաշվի յուրաքանչյուր ուսումնասիրված ֆայլի համապատասխան տողերի քանակը (ներառյալ զրոյական համընկնում ունեցող ֆայլերը).

linux@handbook:~$ grep -irwc --include='*.js' Opal .
...

Հաճախ այդ ելքը որոշակի հետմշակման կարիք ունի, քանի որ այն ցուցադրում է իր արդյունքները այն հաջորդականությամբ, որով ուսումնասիրվել են ֆայլերը, ինչպես նաև ներառում է ֆայլեր՝ առանց որևէ համընկնման, մի բան, որը սովորաբար մեզ չի հետաքրքրում: Այս վերջինը բավականին հեշտ է լուծել.

linux@handbook:~$ grep -irwc --include='*.js' Opal . | grep -v ':0$'

Ինչ վերաբերում է իրեր պատվիրելուն, դուք կարող եք ավելացնել տեսակավորման հրամանը խողովակաշարի վերջում.

linux@handbook:~$ grep -irwc --include='*.js' Opal . | grep -v ':0$' | sort -t: -k2n

Ես թույլ եմ տալիս ստուգել sort հրամանի ձեռնարկը՝ իմ օգտագործած ընտրանքների ճշգրիտ իմաստի համար: Մի մոռացեք կիսվել ձեր գտածոներով՝ օգտագործելով ստորև բերված մեկնաբանությունների բաժինը:

10. Գտնել տարբերությունը երկու համընկնող հավաքածուների միջև

Եթե հիշում եք, մի քանի հրաման առաջ ես փնտրեցի բառը «Օպալ. Այնուամենայնիվ, եթե ես որոնեմ միևնույն ֆայլի հավաքածուում լարի «Օպալ»-ի բոլոր դեպքերի համար, ես կստանամ ևս մոտ քսան պատասխան.

linux@handbook:~$ grep -irw --include='*.js' Opal . | wc -l
86
linux@handbook:~$ grep -ir --include='*.js' Opal . | wc -l
105

Հետաքրքիր կլիներ գտնել տարբերությունը այդ երկու հավաքածուների միջև: Այսպիսով, որո՞նք են անընդմեջ չորս «օփալ» տառերը պարունակող տողերը, բայց որտեղ այդ չորս տառերը մի ամբողջ բառ չեն կազմում:

Այդ հարցին պատասխանելն այնքան էլ հեշտ չէ։ Քանի որ նույն տողը կարող է պարունակել և Opal բառը, ինչպես նաև այդ չորս տառերը պարունակող ավելի մեծ բառ: Բայց որպես առաջին մոտարկում, դուք կարող եք օգտագործել այդ խողովակաշարը.

linux@handbook:~$ grep -ir --include='*.js' Opal . | grep -ivw Opal
./npm/examples.js:  const opalBuilder = OpalBuilder.create();
./npm/examples.js:  opalBuilder.appendPaths('build/asciidoctor/lib');
./npm/examples.js:  opalBuilder.appendPaths('lib');
...

Ըստ երևույթին, իմ հաջորդ կանգառը կլինի opalBuilder օբյեկտի ուսումնասիրությունը, բայց դա կլինի ևս մեկ օր:

Վերջին խոսքը

Իհարկե, դուք չեք հասկանա նախագծի կազմակերպությունը, առավել ևս կոդի ճարտարապետությունը, պարզապես մի քանի grep հրամաններ տալով:

Այնուամենայնիվ, ես գտնում եմ, որ այդ հրամանն անխուսափելի է՝ նոր կոդերի բազան ուսումնասիրելիս որոշելու հենանիշերն ու ելակետերը:

Այսպիսով, հուսով եմ, որ այս հոդվածը օգնեց ձեզ հասկանալու grep հրամանի ուժը, և որ այն կավելացնեք ձեր գործիքի կրծքավանդակում: Անկասկած, դուք չեք զղջա դրա համար: