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?


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.


„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

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.


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


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 „.”


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.


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.


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ę.

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;

-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).

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.