Wypisuj tylko część po ostatnim „/” z funkcją find

-1

To polecenie:

find ./ -name "mybinaryrpm-1.0.24-1.1.i586.rpm"

daje wynik:

./DirectoryName/SubDirectory/mybinaryrpm-1.0.24-1.1.i586.rpm

ale chcę tylko wynik:

mybinaryrpm-1.0.24-1.1.i586.rpm

Jak mogę to zdobyć?


Co tak naprawdę próbuję zrobić:

  1. Przeczytaj plik wejściowy, który zawiera listę nazw plików binarnych oddzielonych od siebie liniami
  2. Wyszukaj pliki o odpowiednich nazwach w bieżącym katalogu rekurencyjnie
  3. Jeśli znaleziono więcej niż jedno dopasowanie, rozważ tylko jeden wynik wyszukiwania i skopiuj plik do odpowiedniego katalogu docelowego.

Aktualny kod:

while read line; do
    binaryRpm=$(find ./ -name "$line" -exec basename {} \;)
    echo " [ Read From File: $line ] <==> [ Find Command Searched: $binaryRpm ]"
    ## If found then copy the binary file to dest dir
    ## TODO: If Find Command finds more than One File with the
    ## Same Name, then ONLY ONE FILE MUST be Compared and copied to
    ## the Release Directory
    if [ "$line" != "$binaryRpm" ]; then
        echo "---------- Binary File Searching---------- "
        continue
    else
        echo " !!!!!! Binary File Found ==> $binaryRpm !!!!!! "
    fi
done < "$FILENAME"
sree
źródło
3
Chcesz wyodrębnić dokładnie ten sam ciąg, który podałeś?
Matteo
-1 Zmęczone wprowadzającymi w błąd pytaniami ...
Daniel Beck

Odpowiedzi:

2

Cóż, twój przykład naprawdę nie ma sensu, ponieważ, jak zauważono w komentarzu, chcesz uzyskać takie same wyniki, jak podajesz jako dane wejściowe. Jeśli znasz dane wejściowe, znasz już dane wyjściowe.

Ale w ogóle, należy użyć find„s -printffunkcję:

find . -name "mybinaryrpm-1.0.24-1.1.i586.rpm" -printf '%f\n'

Z man findsekcji -printf:

%f    File's name with any leading directories removed (only the last element).

Jest to dostępne tylko dla GNU find, ale narzędzia GNU są standardem w Linuksie, o który prosiłeś. Można go również zainstalować na mniej więcej każdej odpowiedniej platformie.


Minimalny przykład kodu, który robi to, co wygląda na to, że naprawdę próbujesz:

#!/bin/sh
FILENAME="/path/to/file/with/filenames"

while read line; do
    binaryRpm=$(find -name "${line}" -type f | head -1)
    if [ -z "${binaryRpm}" ]; then
        echo "No matches found for \"${line}\"."
    else
        echo "Match for \"${line}\" found at \"${binaryRpm}\""
    fi
done < "${FILENAME}"

Komentarze do mojego powyższego przykładu:

  • head -1 zachowa tylko pierwszy mecz.
  • [ -z ]sprawdza, czy zmienna jest pusta (będzie pusta, jeśli findnie znajdzie niczego powyżej).

Komentarze do twojego skryptu:

  • Nie musisz sprawdzać, czy nazwa pliku pasuje do linii, ponieważ findzwróci tylko te, które pasują. Myślę, że używasz go do odrzucania wielu dopasowań, ale headjest to lepsze narzędzie do tego.
  • Nie potrzebujesz continueinstrukcji w niezmienionej postaci, ponieważ skrypt wyskoczy z ifklauzuli i powtórzy forpętlę bezpośrednio po niej.
Daniel Andersson
źródło
Bardzo się cieszę z twoich uwag i odpowiedzi, Sir. Z
poważaniem
[Dodatkowe pytanie] ** Ale powyższe polecenie find wyszukuje i drukuje więcej niż jeden plik o tej samej nazwie. Potrzebuję tylko jednego pliku z wyników wyszukiwania, aby porównać wynik polecenia find z poleceniem odczytu nazwy pliku z pliku.
Wasze
@sree: Musisz zaktualizować swoje pytanie o informacje, co naprawdę próbujesz zrobić. To jest bardzo nieefektywne, abyśmy musieli zgadywać, i wydaje się bardzo prawdopodobne, że istnieje lepszy sposób niż używanie w findten sposób.
Daniel Andersson,
Kroki, które próbuję wykonać
sree
Kroki, które próbuję wykonać, 1. Plik wejściowy ma listę nazw plików binarnych 2. Czytaj plik wiersz po wierszu, aby uzyskać listę nazw plików binarnych 3. Wyszukaj odczytaną nazwę pliku binarnego w bieżącym katalogu lub wszystkich katalogach 4 Porównaj wyszukiwany plik z nazwą pliku binarnego w pliku 5. Jeśli szukany wynik zawiera więcej niż jeden, rozważ tylko jeden wynik wyszukiwania i skopiuj plik do odpowiedniego katalogu docelowego.
sree
0

Wypróbuj to polecenie:

find . -name "mybinaryrpm-1.0.24-1.1.i586.rpm" -exec basename {} \;
kev
źródło
Bardzo się cieszę z twoich uwag i odpowiedzi, Sir. Serdeczne podziękowania ^^
sree
[Dodatkowe pytanie] ** Ale powyższe polecenie find wyszukuje i drukuje więcej niż jeden plik o tej samej nazwie. Potrzebuję tylko jednego pliku z wyników wyszukiwania, aby porównać wynik polecenia find z poleceniem odczytu nazwy pliku z pliku.
Wasze
0

Aby odpowiedzieć na twoje pytanie, możesz spróbować czegoś takiego:

find ./ -name "mybinaryrpm-1.0.24-1.1.i586.rpm" | sed 's|^\..*/\(.*\)|\1|g'

ortang
źródło