Puncte:0

Copiați numai fișierele dintr-o listă într-un director nou dintr-o structură mare de directoare

drapel in

Am o colecție imensă de poze cu flori de când pregătesc o carte. Voi folosi doar câteva dintre ele conținute într-un fișier numit choicen.txt (de fapt un csv). Trebuie să le iau pe cele alese dintr-un arbore de foldere organizat astfel:

Poze
âââ Flori 2020
â  âââ 1.- Primăvara 2020
â  âââ 2.- Vara 2020
â  âââ 3.- Toamna 2020
â  âââ 4.- Iarna 2020
âââ Flori 2021
    âââ 1.- Primăvara 2021
    âââ 2.- Vara 2021
    âââ 3.- Toamna 2021
    âââ 4.- Iarna 2021

10 directoare, 5260 de fișiere

și copiați fiecare imagine de flori aleasă într-un folder nou numit Chosen-one (de exemplu). Sper că am explicat corect ce trebuie făcut.

Mai jos sunt câteva rânduri ale fișierului csv ales.txt

DSC10233.jpg
DSC10276.jpg
DSC10288.jpg
DSC10399.jpg
DSC10448.jpg
DSC10489.jpg
DSC10492.jpg

Este posibil să folosiți Bash sau poate un script Python?

Mulțumesc anticipat.

drapel br
@Vidal pare că la comentariile de mai sus răspundeți de dvs., ultimul lucru este că numele fișierelor din `choen.txt` sunt unice?
user535733 avatar
drapel cn
Sigur că este posibil... dar să te înveți cum să scrii poate dura mai mult decât să faci treaba mai târziu în fluxul tău de lucru. De exemplu, probabil că va trebui să revizuiți manual fiecare imagine oricum în timpul aspectului fiecărei pagini și ar putea fi un moment mai bun pentru a copia fotografiile într-un fișier separat (sau direct în manuscris).
Puncte:3
drapel kr

Sigur, puteți face acest lucru cu un script Bash foarte mic.

Presupun că ai lista ales.txt în directorul dvs. de acasă, din care Imagini este un subdirector. Dacă nu este cazul, vă rugăm să ajustați căile în consecință.

Mai întâi faceți directorul în care mutați fișierele. Presupun că tocmai ați deschis un terminal și vă aflați în directorul dvs. de acasă. Puteți muta directorul mai târziu.

mkdir ChosenOnes

Acum verificați dacă puteți găsi fișierele corecte folosind lista dvs. astfel:

while read -r line; găsiți Imagini -nume "$line" -ls; făcut < ales.txt

Dacă rezultatul pare corect, puteți copia fișierele ajustând comanda:

while read -r line; găsește Imagini -name "$line" -exec cp -vt ChosenOnes {} \; ; făcut < ales.txt

Putem face ca asta să arate puțin mai bine:

#!/bin/bash
# citește lista noastră și
while read -r line; do
  # găsiți fișierele din el și copiați-le în noul director
  find Pictures -name "$line" -exec cp -vt ChosenOnes {} \;
făcut < ales.txt

Explicaţie

  • while read -r line; fa lucruri; done < input-file A in timp ce bucla continuă să facă ceva atâta timp cât o condiție este valabilă. Aici cerem ca lista noastră să fie citită rând cu rând. Fiecare linie va fi introdusă în variabilă linia astfel încât să putem rula niște comenzi(e) pe el. Când terminăm cu comenzile noastre de pe acea linie, următoarea linie va fi citită, până când rămânem fără linii în fișierul nostru.
  • găsiți calea -nume "$line" The găsi comanda face o căutare recursivă în jos de la calea dată (Imagini în cazul nostru). Aici folosim -Nume opțiunea de a găsi fișiere care se potrivesc cu numele din listă.
  • -ls The găsi comanda are o opțiune de a enumera fișierele găsite. Acest lucru este util pentru a verifica ceea ce a fost găsit înainte de a lua orice acțiune
  • -exec comanda {} \; The -exec opțiunea de căutare rulează comanda dată pe fișierele care au fost găsite (reprezentate de {})
  • cp -vt The -v opțiunea face cp spune-ne ce face. The -t opțiunea specifică destinația (dam directorul de destinație imediat după ea); în caz contrar, destinația va fi considerată a fi ultimul argument.
Puncte:2
drapel ar

Da, există mai multe moduri de a face acest lucru pe linia de comandă.

Presupunând că aveți doar o listă de nume de fișiere (fără cale), puteți utiliza a in timp ce buclă pentru a citi fișierul „choen.txt”, găsi pentru a găsi fișierele din folderul sursă și altul in timp ce buclă pentru a le copia.

Definirea variabilelor vă permite să reutilizați comanda lungă fără a fi nevoie să o editați.

list="/path/to/chosen.txt"
source="/cale/spre/Imagini"
dest="/cale/spre/destinație"
pisica „ales.txt” \
| în timp ce citește n; do 
      găsiți „$sursă” -numele „$n” \
      | în timp ce citește f; do
            cp „$f” „$dest/”
        Terminat
  Terminat

Sau pe o singură linie:

pisică „aleasă.txt” | în timp ce citește n; găsiți „$sursă” -nume „$n” | în timp ce citește f; face cp "$f" "$dest/"; Terminat; Terminat

O alternativă, dacă fișierul original .csv conține și calea către fișiere, ar fi să construiți o listă din aceasta. Atunci ai putea folosi rsync cu --files-from= opțiunea de a le copia menținând structura de director originală a sursei.

Zanna avatar
drapel kr
Ooh îmi place ideea `rsync`. Scenariul tău funcționează bine pentru mine.
Vidal avatar
drapel in
Mi-a plăcut și ideea rsync, dar din păcate în acest caz lista nu includea calea fișierelor dorite.
drapel ar
@Vidal: dacă lista nu include calea, rezultatul comenzii find o face.Deci, acesta ar putea fi folosit pentru a face o nouă listă sau poate fi transmis direct în rsync.
Vidal avatar
drapel in
Mulțumiri. Am marcat deja întrebarea ca fiind rezolvată cu bucla while. Cu toate acestea, o voi încerca și cu rsync, deoarece îmi place foarte mult această comandă.

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.