Przenieś pliki według daty do innego katalogu za pomocą CLI


9

Mam dużą liczbę zdjęć ze starego dysku twardego, który próbuję uporządkować. Jeśli uruchomię ls -l, zauważę , że wszystkie te pliki mają datę utworzenia 2012 lub wcześniejszą. Idealnie chciałbym przenieść je na drugi dysk twardy mojego komputera, który nie jest ustawiony do automatycznego montowania. Najlepiej, gdybym mógł to wszystko zrobić jako partię z kilkoma połączonymi ze sobą poleceniami. Do tej pory mam, ls -l | grep -i 2012która wyrzuca tylko pliki z 2012 r. W terminie podanym przez ls -l. Teraz sztuczką byłoby przeniesienie cpwszystkich tych plików do nowego katalogu. Nie jestem pewien, co dalej z tym, ponieważ każdy plik musiałby zostać skopiowany. Jaki byłby mój następny zestaw poleceń?

Odpowiedzi:


13

Nie używać ls. W takich przypadkach nie zaleca się używania. Ponadto używanie grepfiltrowania według daty nie jest dobrym pomysłem. Twoja nazwa pliku może sama zawierać 2012ciąg znaków, nawet jeśli nie została zmodyfikowana w 2012 roku.

Użyj findpolecenia i potokuj jego dane wyjściowe.

find . -newermt 20120101 -not -newermt 20130101 -print0 | xargs -0 cp -t /your/target/directory 

Tutaj,

-newermt 20120101  ==>  File's modified date should be newer than 01 Jan 2012
-not               ==>  reverses the following condition. Hence file should be older than 01 Jan 2013
-print0 and -0     ==>  Use this options so that the command doesn't fail when filenames contain spaces 

1
Nie będzie `-exec mv {} / your / target / directory \; ' zamiast '-print 0 | xargs -0 cp -t / your / target / directory 'działa równie dobrze pod względem problemów ze spacjami w nazwach? (Również OP chciał się przenieść, a nie kopiować )
Hagen von Eitzen

^^ Tak. Oba osiągają ten sam cel.
shivams

4

Jeśli masz stare pliki na starym dysku, które chcesz zignorować, zrobiłbym to w ten sposób

  1. Utwórz tymczasowy plik znaczników ze zmienioną datą, który oddziela pliki, których chcę, od plików, których nie chcę
  2. Skopiuj pliki starsze niż plik znacznika do nowej lokalizacji

Oto przykładowe polecenia, które zakładają, że chcesz zachować hierarchię katalogów ze starego dysku na nowym ( cpiojest to polecenie kopiowania, podobne do tarlub pax):

touch -t 201201010000 /tmp/marker    # YYYYMMDDhhmm == Jan 1st, 2012
cd /path/to/old/disk
find . -type f \! -newer /tmp/marker -print0 | cpio -pmd0 /path/to/new/disk

2

Myślę, że może ten problem jest taki sam jak twój, możesz też to sprawdzić: Twórz podkatalogi i organizuj pliki według daty

Piszę ten nowy skrypt w oparciu o pierwszą odpowiedź na ten problem:

for x in *; do
  d=$(date -r "$x" +%Y)
  mkdir -p "/your/new/directory/$d"
  mv -- "$x" "/your/new/directory/$d/"
done
  1. napisz ten skrypt do pliku o nazwie copy.shw starym katalogu.

  2. zastąp /your/new/directoryścieżkę do nowego katalogu

  3. uczyń ten plik wykonywalnym za pomocą chmod +x copy.sh

  4. następnie uruchom ten plik przez ./copy.sh


1
Możesz dodać obsługę wyjątków, aby skrypt nie przenosił się do 2015katalogu.
G-Man mówi „Reinstate Monica”

1

Prawdopodobnie powinieneś użyć narzędzia wsadowego do operacji wsadowych. Takie postępowanie zazwyczaj wymaga odczytu / zapisu wszystkich rekordów w jednym strumieniu, a nie na przykład wywołania osobnego cpprocesu dla każdego skopiowanego pliku.

Tutaj jest już cpionapisana odpowiedź, która biorąc pod uwagę tylko te opcje, które zapewniono, jest prawdopodobnie tym, co wybrałbym. Jednak cpioformat ten został ulepszony i złożony do znormalizowanego paxformatu archiwum od czasów świetności. To samo dotyczy tar.

Ściśle POSIX- paxprawdopodobnie nie zapewni żadnych opcji bezpośredniego filtrowania elementów archiwalnych na podstawie czasów modyfikacji plików - chociaż standard określa %Tmodyfikator formatu trybu listy. Jednak najbardziej dostępna paximplementacja, o której wiem - czyli wersja BSD obsługiwana przez mirabilos - rozszerza ją na bezpośrednio dostępny przełącznik CLI.

Na przykład, aby skopiować tylko wszystkie pliki w drzewie zakorzenione w ./którym zostały zmodyfikowane przed ccyymmddHHMM, aby /target/dirmożna było zrobić:

pax -rwT,201301010000 ./ /target/dir

Aby uniknąć powtarzania się w katalogach potomnych, możesz zamiast tego:

pax -rwdT,201301010000 ./* /target/dir

Zobacz manstronę po więcej.


Chyba naprawdę powinniśmy się uczyć pax, ale tari cpionadal stać mnie dobrze. +1
roaima

@roaima - ściśle rzecz biorąc, podczas gdy istnieje rzeczywiste paxFormat archiwum (co jest rozszerzeniem ustar formacie) , POSIX-spec''d pax narzędzie odczytuje / zapisuje cpio, pax i ustar formaty. Ponieważ wszystkie trzy typy archiwów sprowadzają się przede wszystkim do różnych sposobów kodowania metadanych dla wielu plików obok rzeczywistych danych wspomnianych plików w jednym strumieniu, nie jest to naprawdę zbyt duże obciążenie. Kiedyś napisałem shitar- co było tylko kilka wierszy skryptu powłoki dla - głównie dd- tartwórców bloków w locie w oparciu o specyfikację POSIX.
mikeserv

Podoba mi się twój link do skryptu; o dziwo byłoby to bardzo przydatne kilka miesięcy temu do dokładnie tego samego celu. No cóż. Mogę nawet spróbować przestać używać cpio -H ustar...
roaima
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.