Chwytając wyjście, by znaleźć. - print0 do tablicy bash
Używając
find. -print0wydaje się być jedynym bezpiecznym sposobem uzyskania listy plików w bashu ze względu na możliwość nazw plików zawierających spacje, znaki nowej linii, cudzysłowy itp.
Jednak ciężko mi jest sprawić, by wynik polecenia find był użyteczny w bashu lub w innych narzędziach wiersza poleceń. Jedynym sposobem, w jaki udało mi się użyć wyjścia, jest potokowanie go do Perla i zmiana IFS perla na null:
find . -print0 | perl -e '$/="\0"; @files=<>; print $#files;'
Ten przykład wypisuje liczbę znalezionych plików, unikając niebezpieczeństwa, że znaki nowej linii w nazwach plików zepsują licznik, tak jak w przypadku:
find . | wc -l
Ponieważ większość programów wiersza poleceń nie obsługuje danych wejściowych rozdzielanych zerami, uważam, że najlepiej jest przechwytywać dane wyjściowe polecenia
find. -print0do tablicy bash, tak jak to zrobiłem w powyższym fragmencie perla, a następnie kontynuuj zadanie, cokolwiek to jest.
W jaki sposób mogę to zrobić?
To nie działa:
find . -print0 | ( IFS=$'\0' ; array=( $( cat ) ) ; echo ${#array[@]} )
O wiele bardziej ogólne pytanie może brzmieć tak:
jak mogę zrobić użyteczne rzeczy z listami plików w bash?
Nie znaleziono powiązanych wyników
Zaproszony:
Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się
13 odpowiedzi
Anonimowy użytkownik
Potwierdzenie od:
Greg BashFAQ
http://mywiki.wooledge.org/BashFAQ/020
:
Zwróć uwagę, że zastosowana tutaj konstrukcja przekierowania ( ) jest podobna, ale nie dokładnie taka sama, jak bardziej konwencjonalny potok ( ) - jeśli polecenia są poleceniami wbudowanymi powłoki (np. ), wersja potoku wykonuje je w podsiatkach, a wszelkie ustawione przez nie zmienne (takie jak tablica ) są tracone przy wyjściu . cmd1 & < & < (cmd2) uruchamia cmd2 tylko na podsiatce, więc tablica żyje po zbudowaniu. Ostrzeżenie: ta forma przekierowania jest dostępna tylko w bash, nawet bash w trybie emulacji sh; musisz uruchomić swój skrypt z .
Ponadto, ponieważ krok przetwarzania pliku (w tym przypadku po prostu
a [i ++] = "$ file"
, ale możesz zrobić coś bardziej wymyślnego bezpośrednio w pętli) przekierowuje jego wejście, nie może używać żadnych poleceń, które można odczytać ze standardowego wejścia. Aby uniknąć tego ograniczenia, zwykle używam:... który przekazuje listę plików przez blok 3, a nie stdin.
Anonimowy użytkownik
Potwierdzenie od:
Opcja -L 1 może być również przydatna dla ciebie, która sprawia, że xargs exec do_something_useful ma tylko 1 argument plikowy.
Anonimowy użytkownik
Potwierdzenie od:
Najpierw tworzymy mały program, który wykonuje za nas tę część:
... i nazwij go base64str (nie zapomnij o chmod + x)
Po drugie, możemy teraz użyć prostej i bezpośredniej pętli for:
Tak więc sztuczka polega na tym, że ciąg base64 jest bez znaku, co powoduje problemy dla basha - oczywiście xxd lub coś podobnego może również wykonać zadanie.
Anonimowy użytkownik
Potwierdzenie od:
Przechwytywanie danych wyjściowych funkcji do tablicy bash
jest:
Anonimowy użytkownik
Potwierdzenie od:
Anonimowy użytkownik
Potwierdzenie od:
(Drukuje nową linię dla każdego znalezionego pliku/katalogu, a następnie zlicza wydrukowane znaki nowej linii ...)
Anonimowy użytkownik
Potwierdzenie od:
Następnie możesz na przykład wyświetlić listę plików jeden po drugim (w tym przypadku w odwrotnej kolejności):
Ta strona
http://bash.cyberciti.biz/file ... file/
podaje dobry przykład, a więcej informacji znajdziesz w
Rozdział 26
http://tldp.org/LDP/abs/html/arrays.html
W instrukcji
Advanced Bash-Scripting Guide
http://tldp.org/LDP/abs/html/
.
Anonimowy użytkownik
Potwierdzenie od:
Anonimowy użytkownik
Potwierdzenie od:
Anonimowy użytkownik
Potwierdzenie od:
Aby otrzymać fakturę:
echo ${#files[@]}
Anonimowy użytkownik
Potwierdzenie od:
Anonimowy użytkownik
Potwierdzenie od:
Najpierw umieść ciąg w zmiennej:
Następnie usuń tę zmienną i zapisz ją w tablicy:
Jest jedna sztuczka: to znak NUL. Aby to zrobić, musisz nacisnąć Ctrl + V, a następnie Ctrl + @.
Możesz sprawdzić, czy każdy rekord $ B zawiera poprawną wartość:
for i in "$B[@]"; echo \"$i\"
Wnikliwi czytelnicy zauważą, że wywołania polecenia w większości przypadków można uniknąć, używając składni . Na przykład:
Anonimowy użytkownik
Potwierdzenie od:
Zamiast tego zalecałbym używanie Pythona z biblioteką sh.