Fragment Bash, aby przenieść wszystkie pliki z katalogu do tego katalogu

14

Mam katalog z dużą ilością plików i katalogów. Aby to uporządkować, zamierzam umieścić wszystkie te pliki w katalogu, więc zamierzałem zrobić coś takiego:

$ ls | wc -l
123
$ mkdir new_directory
$ mv * ./new_directory

Jednak, że oczywiście nie będzie działać, bo wtedy będzie starał się przenieść new_directoryna new_directory. Czy jest jakiś prosty sposób na zrobienie tego, co chcę w jednym wierszu bez konieczności kopiowania i wklejania wszystkich plików i katalogów w tym katalogu?

Rory
źródło
3
to działa, po prostu drukuje komunikat o błędzie, że nie jest w stanie przenieść nowego_katalogu do siebie.
cas

Odpowiedzi:

18

Twój

mv * ./new_directory
polecenie faktycznie będzie działać; po prostu wydrukuje ostrzeżenie, że nie może przenieść tego katalogu do siebie.

mibus
źródło
„Jedynym” problemem jest to, że jeśli całkowite rozwinięcie polecenia stanie się zbyt długie (tj. Zbyt wiele plików, zbyt długie nazwy), to przestanie działać.
Niels Basjes,
Na marginesie, jeśli masz zamiar to zrobić z flagą, git mvmusisz użyć -kflagi, ponieważ git domyślnie zawiedzie, a nie tylko wyrzuci ostrzeżenie. Więc musisz to zrobić git mv -k * ./new_dir.
Yuval A
11

Szybki i brudny oneliner.

mv `ls -A | grep -v new_directory` ./new_directory

źródło
1
Nie będzie działać: zwykły ls nie pokaże plików dot.
wzzrd
Bardzo dobra uwaga. Naprawiono to za pomocą -a.
2
Zamiast próbować utworzyć nowy katalog dla siebie (pytanie oryginalne), próbujesz się teraz przenieść. i .. do nowego_katalogu.
Niels Basjes,
2
Dzięki za opinie, Niels. Naprawiono go górną częścią, która usuwa. i ... z listy katalogów.
8

Jeśli szukasz tylko plików (tzn. Nie katalogów), to

find . -type f -maxdepth 1 -exec mv {} ./new_directory/ \;

jest najbardziej przenośnym rozwiązaniem. Aby zwiększyć szybkość, powinieneś przenosić find i xargs, używając -print0 i -0, ale tylko jeśli masz GNU find i xargs.

Cian
źródło
3
Używając dość niedawnego znalezienia GNU, możesz również użyć \ + zamiast \; aby zmniejszyć liczbę wytwarzanych przez nas mv.
wzzrd
Jeśli masz GNU find, równie dobrze możesz użyć xargs, który zrobi to samo i pozwoli ci uruchamiać wiele mvów jednocześnie z flagą -p.
Cian
fajne użycie find- chociaż zdecydowanie byłem na systemach, które nie mają, niestety :(
warren
Naprawdę? find jest (afaik) określony w SUS, więc wszystko powinno go mieć. Jedynym problemem jest to, czy jest to GNU find (który ma wiele fajnych fajnych opcji), czy zwykłe find.
Cian
Tak, wygląda na to, że jest opengroup.org/onlinepubs/009695399/utilities/find.html
Cian
6

Kiedy miałem ten problem, robiłem jedną z następujących czynności:

$ mkdir ../new-directory
$ mv * ../new-directory/
$ mv ../new-directory .

lub

$ mkdir .new-directory
$ mv * .new-directory/
$ mv .new-directory new-directory

Druga forma korzysta z symboli wieloznacznych pomijających nazwy plików, które zaczynają się od „.”

Kenster
źródło
Zapomniałem pomijanych plików z kropkami; dzięki za przypomnienie ! :)
aemonge
2

co powiesz na:

cd ..
mv old_dir new_directory
mkdir old_dir
mv new_directory old_dir

IOW, nie przenoś zawartości do nowego katalogu, ale umieść ten katalog w nowym.

Javier
źródło
1

W podobny sposób jak odpowiedź @ Rembrane (choć nie jest to jedna linijka):

for FN in *
do
    if [ "<new_dir>" != $FN ] then
        mv $FN <new_dir>
done

Powinno to być w 100% przenośne - nawet jeśli findniestety nie ma go w twoim systemie.

królikarnia
źródło
find jest wymagany w specyfikacji pojedynczego unixa. Jako taki, nigdy nie powinien być nieobecny (nie to, że nie można zbudować czegoś bez niego. Ale wyobrażam sobie, że wymagałoby to ogromnego wysiłku, a żaden system sprzedawcy nie będzie tego brakować)
Cian
może to jakiś hiper-paranoidalny sysadmin szukający findutils lub jego odpowiednika? nie jestem pewien, ale wiem, że wpadłem na boxena, który go nie ma :(
warren
1

Moje sugestie: jak stwierdzili inni

mv * ./new_directory

będzie działać, aby znaleźć IFF, całkowite rozszerzenie jest wystarczająco krótkie.

Z drugiej strony możesz wypróbować ten, który skaluje się do znacznie większej liczby plików:

find . -type f -maxdepth 1 | xargs -s100000 echo | xargs -iXXX mv XXX new_directory

Wyjaśnienie

  1. Wyświetl wszystkie pliki.
  2. Pogrupuj wszystkie nazwy plików na części o maksymalnej długości 100 000 znaków.
  3. Skonstruuj pojedyncze polecenie mv na porcję.
Niels Basjes
źródło
pęka, jeśli w nazwach plików są spacje
Cian
Masz rację. Sądzę więc, że należy to uzupełnić flagami -print0 i -0, aby to naprawić.
Niels Basjes
Próbowałem z -print0i -0i nadal przerw.
Cristian Ciupitu,
find: ostrzeżenie: podano opcję -maxdepth po argumencie innym niż -type, ale opcje nie są pozycjonowane (-maxdepth wpływa na testy określone przed nim, a także na testy określone po nim). Proszę podać opcje przed innymi argumentami.
Cristian Ciupitu,
1

Posługiwać się:

find -mindepth 1 -maxdepth 1 \! -name new_directory -print0 | \
    xargs -0 -P 100 -I'{}' mv '{}' new_directory

Ze strony podręcznika xargs:

-P maks. Proc

  Run up to max-procs processes at a time;
Cristian Ciupitu
źródło
-1

Aby uniknąć komunikatu o błędzie i uprościć:

mv *.* ./new_Folder

zrobi to samo, ale uniknie komunikatu o błędzie (chyba że w nazwach folderów są kropki).

użytkownik157734
źródło