Jak zawsze, uważaj grep -r. -rnie jest standardową opcją, a w niektórych implementacjach, takich jak wszystkie oprócz najnowszych wersji GNU grep, podąża za dowiązaniami symbolicznymi podczas schodzenia z drzewa katalogów, co na ogół nie jest tym, czego chcesz i może mieć poważne konsekwencje, jeśli na przykład istnieje dowiązanie symboliczne do „/ „gdzieś w drzewie katalogów.
W filozofii uniksowej używasz polecenia do przeszukiwania katalogów w poszukiwaniu plików, a drugiego do przeglądania jego zawartości.
Ale nawet wtedy uważaj na warunki wyścigu i możliwe problemy z bezpieczeństwem, jeśli uruchomisz go jako jeden użytkownik w katalogu, który może zapisać inny użytkownik.
to daje mi błąd find: `grep 'zakończony sygnałem 13. jakiś pomysł co się dzieje?
Reena Parekh,
@ReenaParekh, to byłby SIGPIPE. Stałoby się tak tylko, jeśli wyjdzie xargsprzed przeczytaniem do końca pliku arg, co nie powinno się zdarzyć, chyba że xargs zostanie zabity sam lub zawiedzie z jakiegokolwiek powodu, w takim przypadku spodziewam się, że również zobaczysz błąd.
Stéphane Chazelas,
15
Użyj xargsw połączeniu z mvtrzecią składnią:mv [OPTION]... -t DIRECTORY SOURCE...
grep -lir 'string' ~/directory/* | xargs mv -t DEST
Uważaj na pliki zawierające znaki specjalne (spacje, cudzysłowy). W takim przypadku filtrowanie listy za pomocą sed(dodawanie cudzysłowów wokół nazw plików za pomocą s/^/'/;s/$/'/) może pomóc, ale musisz mieć pewność, że te cytaty nie pojawią się w nazwach plików. GNU grepma opcję -Z/ --null, aby zakończyć nazwy plików na NUL.
Alternatywą dla trzeciej składni mvjest użycie xargsz symbolem zastępczym string ( -I).
Inną opcją jest podstawianie poleceń - $( )lub backsticks ``(w bash), jak wspomniano w odpowiedzi ire_and_curses.
gnu grep obsługuje flagę -Z do oddzielania nazw plików od znaku bajtu zerowego, który w połączeniu z flagą -0 dla xargs może ominąć problem ze znakami specjalnymi, o których wspomniałeś
grep -i -Z -r -l 'string' . | xargs -I{} mv {} ./folder_name
Odpowiedzi:
Jak zawsze, uważaj
grep -r
.-r
nie jest standardową opcją, a w niektórych implementacjach, takich jak wszystkie oprócz najnowszych wersji GNUgrep
, podąża za dowiązaniami symbolicznymi podczas schodzenia z drzewa katalogów, co na ogół nie jest tym, czego chcesz i może mieć poważne konsekwencje, jeśli na przykład istnieje dowiązanie symboliczne do „/ „gdzieś w drzewie katalogów.W filozofii uniksowej używasz polecenia do przeszukiwania katalogów w poszukiwaniu plików, a drugiego do przeglądania jego zawartości.
Korzystając z narzędzi GNU, zrobiłbym:
Ale nawet wtedy uważaj na warunki wyścigu i możliwe problemy z bezpieczeństwem, jeśli uruchomisz go jako jeden użytkownik w katalogu, który może zapisać inny użytkownik.
źródło
xargs
przed przeczytaniem do końca pliku arg, co nie powinno się zdarzyć, chyba że xargs zostanie zabity sam lub zawiedzie z jakiegokolwiek powodu, w takim przypadku spodziewam się, że również zobaczysz błąd.Użyj
xargs
w połączeniu zmv
trzecią składnią:mv [OPTION]... -t DIRECTORY SOURCE...
Uważaj na pliki zawierające znaki specjalne (spacje, cudzysłowy). W takim przypadku filtrowanie listy za pomocą
sed
(dodawanie cudzysłowów wokół nazw plików za pomocąs/^/'/;s/$/'/
) może pomóc, ale musisz mieć pewność, że te cytaty nie pojawią się w nazwach plików. GNUgrep
ma opcję-Z
/--null
, aby zakończyć nazwy plików na NUL.Alternatywą dla trzeciej składni
mv
jest użyciexargs
z symbolem zastępczym string (-I
).Inną opcją jest podstawianie poleceń -
$( )
lub backsticks``
(w bash), jak wspomniano w odpowiedzi ire_and_curses.źródło
Jeśli nazwy plików nie zawierają żadnych znaków specjalnych (białe znaki lub
\[*?
), użyj podstawienia polecenia :źródło
Używając tylko określonych funkcji POSIX i nie przyjmując żadnych założeń dotyczących nazw plików:
Uwagi:
Powiedziałeś „ciąg” nie „wzorzec”, więc
-F
opcja (naprawione wyszukiwanie ciągów)grep
wydaje się odpowiednia.Jeśli katalog docelowy znajduje się w dowolnym miejscu w katalogu wyszukiwania, możesz mieć nieprzyjemne warunki wyścigu.
Specyfikacja POSIX dla
grep
Specyfikacja POSIX dla
find
źródło
Używanie GNU równoległego :
ht / @ lin-dong za oryginalną odpowiedź na xargs.
źródło
-Załóż, że masz katalog docelowy jako „zewnętrzny” i musisz przenieść wszystkie pliki XLS, możesz wypróbować poniższe polecenie
sudo mv
find /var/log/ -type f -name "*.xls"
/ external /źródło