Vraag Hoe te grep voor tabbladen zonder gebruik te maken van letterlijke tabbladen en waarom werkt het niet?


Wanneer ik naar tabbladen in een bestand met (e) grep zoek, gebruik ik het tabblad litteral (^v + <tab>). Ik kan het niet gebruiken \t als vervanging voor tabbladen in reguliere expressies. Met b.v. sed deze uitdrukking werkt heel goed.

Dus is er een mogelijkheid om een ​​niet-literaire vervanging te gebruiken voor <tab> en wat zijn de achtergronden voor een niet-werkende / niet-geïnterpreteerde \t ?


117
2017-07-14 11:59


oorsprong


stackoverflow.com/questions/1825552/grep-a-tab-in-unix - Ciro Santilli 新疆改造中心 六四事件 法轮功


antwoorden:


grep gebruikt reguliere expressies zoals gedefinieerd door POSIX. Om welke reden dan ook die POSIX niet heeft gedefinieerd \t als tabblad.

Je hebt verschillende alternatieven:

  • vertel grep om de reguliere expressies te gebruiken zoals gedefinieerd door perl (perl heeft \t als tabblad):

    grep -P "\t" foo.txt
    

    de man-pagina waarschuwt dat dit een "experimentele" functie is. minstens \t lijkt goed te werken. maar meer geavanceerde perl regex-functies misschien niet.

  • gebruik printf om een ​​tab-teken voor u af te drukken:

    grep "$(printf '\t')" foo.txt
    
  • gebruik het lettertabbladteken:

    grep "^V<tab>" foo.txt
    

    dat is: type grep "en druk vervolgens op ctrl+ven druk vervolgens op tab, typ dan " foo.txt. persing ctrl+v in de terminal zorgt ervoor dat de volgende toets letterlijk wordt overgenomen. dat betekent dat de terminal een tab-teken invoegt in plaats van een functie te activeren die is gekoppeld aan de tab-toets.

  • gebruik de ansi c citeren kenmerk van bash:

    grep $'\t' foo.txt
    

    dit werkt niet in alle shells.

  • gebruik awk:

    awk '/\t/'
    
  • gebruik sed:

    sed -n '/\t/p'
    

Zie de wikipedia-artikel over reguliere expressies voor een overzicht van de gedefinieerde tekenklassen in POSIX en andere systemen.


164
2017-07-14 15:04



baserend op het antwoord van enzotib voeg ik het volgende toe: grep $'\t' foo.txt (maar ik zou meestal schrijven fgrep in plaats van grep) - Walter Tross
Ik had dit nodig, gecombineerd met het gebruik van de waarde van een omgevingsvariabele. ik gebruikte grep "$(printf '\t')${myvar}" foo.txt. Het werkte prima. Met een paar pogingen kon ik de laatste vorm niet laten werken. - sancho.s
Is er een reden die duidelijk is grep kon niet stil interpreteren \t als tabblad? Vereist POSIX dit \t iets anders betekenen? Misschien moet het alleen een letterlijke vergelijking zijn \  gevolgd door een t? - Aaron McDaid
Misschien is het vermeldenswaard dat BSD (inclusief OSX) grep de optie -P mist. - TextGeek
Van de man-pagina This is highly experimental and grep -P may warn of unimplemented features. Waarschijnlijk geen goed idee om te gebruiken -P in legacy-systemen. De printf keuze is beter - Avindra Goolcharan


Het is niet precies het antwoord dat je zou willen horen, maar een mogelijk gebruik van escape-sequences wordt geboden door bash

command | grep $'\t'

(plaats het niet in dubbele aanhalingstekens!).


12
2017-07-14 14:15



er is geen noodzaak voor de -E (waarnaar wordt gezocht is geen regex). Het is ook niet nodig om uit een commando te pipen. Dat gezegd hebbende, bedankt voor het wijzen op deze vrij over het hoofd geziene functie van bash (enkele aanhalingstekens voorafgegaan door $) - Walter Tross
Ik stel zelfs voor dat @enzotib het antwoord eenvoudig zou kunnen bewerken grep $'\t'. - Teemu Leisti
Het moet benadrukt worden dat dit een kenmerk is van bash en zal (stil!) Het verkeerde doen als het uitgevoerd wordt door een andere shell (zoals een streepje, wat de standaard is voor shellscripts op Ubuntu en anderen) - xjcl


awk '/\t/' is mijn favoriete oplossing:

printf 'a\t\nb' | awk '/\t/'

Output: a\t.


2
2017-08-28 11:15





Men kan altijd gebruik maken van ascii hex-code voor tab:

$ echo "one"$'\t'"two" > input.txt                                 

$ grep -P "\x9" input.txt                                          
one two

$ grep $'\x9' input.txt                                            
one two

1
2017-07-03 17:04