Bash: Bir dosya dizininde belirli bir dize aramanın bir yolu var mı? [çift]


47

Olası Çoğalt:
Linux'ta bir metin deseni arayın

Kısaca, aradığınız dizinde bulunan dosyalar içinde aradığınız belirli bir dizginin olup olmadığını size bildirecek herhangi bir komut olup olmadığını merak ediyordum.

Şu anki dizininizdeki C dosyalarının içindeki 'toUpperCase ()' işlevini aradığınızı varsayalım. Çok fazla dosya var, bu yüzden her birini vim kullanarak manuel olarak açmak ve 'toUpperCase' dizesini kontrol etmek istemezsiniz çünkü bu çok zaman alır. Bir bash komut satırı değilse, bunu verimli bir şekilde yapmanın başka bir yolu var mı?

Yanıtlar:


64

İle grep:

grep -R "toUppercase()" *

Veya, bir ack-grep kurulu ise, basitçe:

ack-grep "toUppercase"

Aramayı C dosyalarında sınırlandırmak istiyorsanız, şunlarla ack-grep:

ack-grep -cc "toUppercase()"

ack-grepOSX üzerine de kurulabilir ancak çalıştırılabilir dosyaya sadece ad verilir ack.


Öyle ki, SO zaten kuşkuyla benzer bir soruya sahip ;)
David Perry

10

Standart metin arama aracı grep'tir .

Geçerli dizindeki toUpperCase(tüm .cdosyalarda dizeyi aramak için :

grep -F 'toUpperCase(' *.c

Ayrıca alt dizinlere de bakmak istiyorsanız:

grep -r --include='*.c' -F 'toUpperCase('

C işlev çağrıları arıyorsanız, etiketler daha uygun olabilir. Bir tanımlayıcı dizini oluşturmak için tüm kaynak dosyalarınızda bir kez çalıştırın, ardından çağrılar arasında gezinmek için editörünüzü kullanın. Tüm vi-editörleri ctags'ın TAGSdosyasını kullanabilir . Emacs kullanıyorsanız, benzer programı çalıştırın etags.


ctagsfonksiyonu bulmak için yararlıdır tanımları , değil işlev çağrıları .
JdeBP

6

Vim kullanıyorsun. Bunu yapmak için bir aracın var.

Tahmin edilebileceği gibi, kullanmak için zaten söylenen yedi cevap var grep. Ama şu ana kadar kullandığın sorundan farkeden tek kişi benim gibi görünüyor vim. Eğer rağmen Gibi, olabilir kullanmak grepiçinden vimşunları yapabilirsiniz ayrıca kullanmak vim'ın aracında yerleşik. Bu :vimgrepkomut aracılığıyla çağrılır .

"Geçerli C dizinindeki tüm C kaynak dosyalarının fonksiyon çağrıları için aranması toUpperCase()" vimkomutunu yazın.

:vimgrep "\<toUpperCase\_s*(" *.c

Sonuçta ortaya çıkan eşleşme listesi otomatik olarak hızlı düzeltme listesine yüklenir, bunlardan biriyle erişilebilir (ince farkın çevrimiçi yardımına bakın)

:copen
:cwin

Çağrılar yerine işlev tanımını bulmak için , cevabındactags belirtildiği gibi , veya komutları ile birlikte bir araçtır .Gilles:tjump:tselect

Neden kullanılmalı :vimgrep?

On-line yardım ( :help grep), burada papağan olmayacağım sebeplerin bir çoğunu içerir. Daha olanlara, eylemini karşılaştırmak :vimgrepo ile dietbuddhabireyin cevabı . dietbuddhakomut satırı grep, her bir C kaynak dosyası için ayrı bir işlem öngörür . Bu xargsek yükü azaltmak için bile istihdam etmiyor . Ve yine de bir şekilde metin editörünüzü bitirdikten sonra ilgili kaynak dosyalara çağırmak için çıktıyı ayrıştırmanız gerekir. :vimgrepbirden fazla ek işlemi hiçbir zaman engellemiyor ve sonucu kullanmak basitliğin kendisi. Sonuçtaki hızlı düzeltme listesindeki girişlerden yalnızca birini seçmek, imleci otomatik olarak ilgili kaynak dosyanın ilgili satırına yerleştirir.

Aslında, otomatik olarak hariç, elle yaptığınız şeyi tam olarak yazar. Bu metin editörü işlemlerini yapmanın otomatik yolu. Dosyayı elle yüklüyormuş gibi yükler, düzenli bir ifade arar ( daha önce başka bir yerde kullandığınız aynı düzenli ifade sözdizimini kullanarak vim), eşleşmelerin gerçekleştiği yerleri kaydeder ve ardından dosyayı kaldırır.


2

Evet, araç denir grep.

Grep komutu, belirtilen bir düzenle eşleşmeyi içeren satırlar için bir veya daha fazla giriş dosyasını arar. Grep varsayılan olarak eşleşen satırları yazdırır.

Temel kullanım:

grep something somewhere

Veya daha spesifik olarak:

grep [some options] pattern file

Çok basit bir durumda, sürekli olarak tüm dosyaları aramak istersiniz, böylece -rseçeneği sunarsınız. Büyük veya küçük harf umurunda değilse, -iseçeneği büyük / küçük harf duyarlı hale getirin .

grep -ri "touppercase()" .

Yalnızca eşleşen parçaları istiyorsanız, -oseçeneği kullanın.

Grep normal ifadeler kullanabilir ve çok büyük bir kullanım kılavuzu vardır .


2

grepStandart Cevap - yinelemeli veya birlikte ya arama -r bayrağını kullanarak find(tartışma ve bu şekilde bu sitede diğer sorular, örnekler bu bir )

Son zamanlarda tercih ettiğim seçim ack. Bilgisayarınızda yüklü olması muhtemel değildir, ancak Ubuntu'da apt-get komutunu kullanarak kurabilir ya da sadece indirebilirsiniz. Bağlantılardan, talimatlardan ve grep'ten daha iyi olmasının sebepleri http://betterthangrep.com/ adresinde bulunabilir.


1

find ve grep

find myproject -name '*.c' -exec grep 'toUpperCase(' {} \; -print

Neden sadece grep?

grep -r string .geçerli dizindeki tüm dosya üzerinden tekrarlanacaktır. Nesne dosyalarınız veya diğer ikili dosyalarınız varsa, ikili sonuçlara sahip aka bir eşleşme geri alabilirsiniz. Önemsiz. Ayrıca, alt dizinde beş dosya veya cihaz dosyalarınız varsa, bilinmeyen / istenmeyen sonuçlar doğurabilir.

grep string *.csadece geçerli dizin .cdosyalarını arar .

grep string **/*.c tüm alt dizinleri arar. Bununla birlikte, çok fazla sayıda .cdosyanız varsa, kabuk küresi için maksimum genişletme sayısını aşma riskiyle karşı karşıya kalırsınız. Genişleme ilk önce gerçekleşmeli, yani grepbaşlamadan önce tam bir ağaç geçişi demektir .


0

Grep hile yapacak, ancak bir miktar ek komut dosyası, dosyanın adını ve başvurulan tam satırı bulmaya yardımcı olacaktır. Eğer istediğin buysa, aşağıdakileri iyi buluyorum. Bir kabuk betiği olarak kaydettim ve ilk komut satırı seçeneği olarak istediğim değeri ilettim.

for i in $(ls)
do
    cat $i 2> /dev/null | grep $1 > /dev/null 2>&1
    STATUS=$?
    if [ $STATUS  -eq 0 ] ; then
        echo $i
        cat $i | grep -n $1
    fi
done

3
grep, bunu zaten yapan bir -H seçeneğine sahiptir. grep -Hn ne olursa olsun *
Roy Rico,

Her gün yeni bir şeyler öğrenin .. Thanks @Roy Rico
Tim Brigham

0

Kimsenin sizin özel sorunuza cevap vermemesini ilginç buluyorum: "o anki dizinde bulunan dosyalar içerisinde belirli bir dizgenin var olup olmadığını nasıl bulurum". Bildiğim kadarıyla sadece bir grup dosyada bir eşleşme bulunup bulunmadığını döndüren hiçbir grep seçeneği yoktur. En yakın seçenek dosya isimlerini listelemek için -l'dir. Şu ana kadarkiler arasında en yakın cevap, bazı ufak tefek rakamlarla Tim'den geldi:

#!/usr/bin/bash

for i in $(ls *.c 2> /dev/null)
do
    cat $i 2> /dev/null | grep $1 > /dev/null 2>&1
    STATUS=$?

    if [ $STATUS  -eq 0 ] ; then
        echo "Found"
        exit
    fi
done

echo "Not found"

Çok fazla sorun yaşamadan dosya uzantısı için ikinci bir argüman kabul ederek bu kabuk betiğini daha genel hale getirebilirsiniz.

Doug

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.