Nowe posty

xx Dystrybucja pod HP Omen (6)
2024-03-27, 23:30:08
xx [Poradnik] Wyszukiwanie Sterowników (2)
2024-03-27, 21:08:23
lamp Problem z Linux Lite po instalacji (0)
2024-03-27, 19:50:30
xx Ile pingwinów? (1)
2024-03-27, 08:59:24
xx konfiguracja pale moon (0)
2024-03-24, 21:53:42
xx Plasma 6 w Neonie ssie trochę mniej ... (10)
2024-03-23, 02:38:11
xx problem z instalacja sterowników do karty sieciowej (3)
2024-03-18, 18:10:16
xx Plik abc.001 (1)
2024-03-17, 17:48:27
xx Zlecę dopracowanie programu w MatLab (0)
2024-03-13, 15:28:40
xx Linux Mint 21.3 XFCE brak dźwieku po paru minutach (karta muzyczna zintegrowana) (5)
2024-03-12, 23:07:01

Autor Wątek: Skrypt- wyszukiwanie nazwy w tresci plikow  (Przeczytany 4526 razy)

witu12

  • Gość
Skrypt- wyszukiwanie nazwy w tresci plikow
« dnia: 2017-05-23, 01:33:53 »
Witam. Jest to mój pierwszy post.
Moim zadaniem jest napisanie skryptow ktory wypisze nazwy plikow z katalogu bierzacego, ktorego nazwa i tresc zawierają tekst /*main*/. oto moj niedziałajacy kod:

for i in `ls -la`
do
   if  [ ! -d $i ]; then
plik= `head $i`

  id [ "$plik" = '/*main*/' ]; then

echo $i
echo " znalazlem plik"

fi
fi
done

Offline 1709

  • Users
  • Guru
  • *****
  • Wiadomości: 2763
  • 1709
    • Zobacz profil
Odp: Skrypt- wyszukiwanie nazwy w tresci plikow
« Odpowiedź #1 dnia: 2017-05-23, 13:40:46 »
1. Przygotowalem sobie  przyklad , dwa pliki z czego do jednego wrzucilem
int main() { cout << "hello"; system("pause"); return 0; }
Nie wiem czy main ma byc z gwiazdkami czy bez ...

2. Odpalam skrypt
$ ./test
./test: linia 9: błąd składni przy nieoczekiwanym znaczniku `then'
./test: linia 9: `  id [ "$plik" = '/*main*/' ]; then'

3. Przyglądam się liniom pokolei
 " for i in `ls -la` "

Polecenie ls -la wykonane w terminalu
$ ls -la
razem 44
drwxr-xr-x 2 tx tx 4096 maj 23 13:06 .
drwxr-xr-x 3 tx tx 4096 maj 11 16:53 ..
-rwxr-xr-x 1 tx tx 9976 maj 13 21:55 a
-rw-r--r-- 1 x tx 1237 maj 13 21:55 a.c
-rw-r--r-- 1 tx tx 1951 mar 24  2011 f.png
-rw-r--r-- 1 tx tx 8227 maj 23 13:06 ron
-rwxr-xr-x 1 tx tx  158 maj 23 13:03 test
Lepiej przyjżyj sie jak taka petla działa, a własciwie czego potrzebuje, wykonujac przyklady w terminalu
https://www.cyberciti.biz/faq/bash-for-loop/

Zróbmy sobie przyklad
#!/bin/bash

for i in `ls -la`
do
     echo $i
done
Odpalmy teraz skrypt do celów testowych , a oto fragment wyniku
$ ./test
razem
44
drwxr-xr-x
2
tx
tx
4096
maj
23
13:16
.
drwxr-xr-x
3
tx
tx
4096
maj
11
16:53
..
-rwxr-xr-x
...
Wydzisz coś zrobił ? Zeby to poprawnie dzialalo byś musiał użyć komendy lub lini komend które wyswietlą  tylko nazwy plików.

No to teraz naprawmy to
- stwórzmy ową komende która wyświetli tylko pliki  ( wykonamy komende w terminau )
$ ls -la | grep ^"-" | awk '{printf $9 " " }'
a a.c f.png ron test
No widać działa, wyszukało tylko pliki, a po " | awk '{printf $9 " " }' " pokazuje tylko ostatnia kolumne , czyli nazwy plików

Przetestujmy to w pętli for, czyli w skrypcie
#!/bin/bash

for i in `ls -la | grep ^"-" | awk '{printf $9 " " }'`
do
     echo $i
done

A oto wynik skryptu:
$ ./test
a
a.c
f.png
ron
test


- skoro mamy nazwe pliku to teraz jak wyszukać w pliku jakąś nazwe ?

id [ "$plik" = '/*main*/' ]; then
Co to jest " id " ?
Cytuj
id

Print real and effective user id (uid)
https://ss64.com/bash/id.html
Napewno oto Ci chodziło ?

Wpisz w wyszukiwarce internetowej " linux wyszukiwanie znakow  w pliku "
Dzieki znalezionym skąpym ale jednak informacjom dowiesz się że do wyszukiwania plików używa się komendy find
a do wyszukiwania w plikach grep i owe znaki w pliku to ciągi znaków.
Wystarczy że poszperasz w internecie  a znajdziesz przyklady.

Teraz poczekam, czy znajdziesz jakies przykłady. Staraj się szukać także po angielsku.
Napiszę tylko że zamiast pętli możesz użyć find.
PS: Brak polskiej czcionki, nie jest to brak lenistwa, a jej brak w systemie i brak czasu na reczne poprawki.

Offline 1709

  • Users
  • Guru
  • *****
  • Wiadomości: 2763
  • 1709
    • Zobacz profil
Odp: Skrypt- wyszukiwanie nazwy w tresci plikow
« Odpowiedź #2 dnia: 2017-05-24, 16:46:33 »
Chyba nie miałeś czasu szukać,

Przykłady:
Cytuj
$ grep -i "main" *
Plik binarny a pasuje do wzorca
a.c:int main(int argc, char **argv) {
a.c:        gtk_main();
grep: nowy katalog: Jest katalogiem
ron:int main() { cout << "hello"; system("pause"); return 0; }
Na zielono masz pliki i katalogi, tak działa grep, w przyjaznej formie, a reszta to zawartość pliku
więcej znajdziesz  w poleceniach ( wykonanych w terminalu )
man grep
grep --help


I jak się pobawisz opcjami grep to osiągniesz to co pewnie chciałbyś,
 czyli tylko pliki , tylko pliki tekstowe, z pominięciem katalogów  i tylko zawierające słowo "main"
$ grep -lId skip "main" *
a.c
ron

W twojej pętli wyglądałoby to tak
#!/bin/bash

for i in `ls -la | grep ^"-" | awk '{printf $9 " " }'`
do
grep -lI "main" $i && echo " znalazlem plik"
done
Czyli grep sprawdza plik i jeśli wynik będzie pozytywny zostanie wykonana komenda "  echo " znalazlem plik"  "

A oto wynik skryptu
$ ./test
a.c
 znalazlem plik
ron
 znalazlem plik
test
 znalazlem plik
Działa idealnie ?
Moim zdaniem działa, tylko po co pisac skrypt jak można uzyć samej komendy grep z opcjami jak wyżej  ;D
( a plik test, to owy skrypt który uruchamiałem )

A teraz przykład z find , oco mi chodziło ?
$ find . -type f | xargs grep -lI "main" 
./ron
./test
./a.c
find wyszuka w  ". " bierzącym katalogu , typ pliki " f " i nastepnie komenda grep "-l " wyswietla tylko nazwy plików , " -I "  bez plików binarnych i ze słowem "main"         
Oczywiście jak wyżej już wspomniałem można użyć samo grep , z możliwością podania scieżki do kataloguoraz czy rekurencyjnie w podkatalogach czy nie,
 a pętle for możemy stworzyć gdy potrzebujemy wykonać bardziej skomplikowane operacje na pliku.

Edytowane:
$ find . -type f | xargs grep -lI "main" |  awk '{ print $1, "\n znalazłem plik" }'
./ron
 znalazłem plik
./test
 znalazłem plik
./a.c
 znalazłem plik

$ grep -lId skip "main" * | awk '{ print $1, "\n znalazłem plik" }'
a.c
 znalazłem plik
ron
 znalazłem plik
test
 znalazłem plik

PS: Brak polskiej czcionki, nie jest to brak lenistwa, a jej brak w systemie i brak czasu na reczne poprawki.