Jeg søker etter filer hvis navn inneholder AAA
i banen ved hjelp av følgende kommando:
find path_A -name "*AAA*"
Gitt utdataene fra kommandoen ovenfor, ønsker jeg å flytte disse filene til en annen sti, for eksempel sti_B
. I stedet for å flytte filene én etter én, kan jeg optimalisere kommandoen ved å flytte filene rett etter find-kommandoen?
Med GNU mv:
find path_A -name '*AAA*' -exec mv -t path_B {} +
Det vil bruke find's -exec
opsjon som erstatter {}
med hvert find-resultat etter tur og kjører kommandoen du gir den. Som forklart i man find
:
-exec command ;
Execute command; true if 0 status is returned. All following
arguments to find are taken to be arguments to the command until
an argument consisting of `;' is encountered.
I dette tilfellet bruker vi +
-versjonen av -exec
slik at vi kjører så få mv
-operasjoner som mulig:
-exec command {} +
This variant of the -exec action runs the specified command on
the selected files, but the command line is built by appending
each selected file name at the end; the total number of invoca‐
tions of the command will be much less than the number of
matched files. The command line is built in much the same way
that xargs builds its command lines. Only one instance of `{}'
is allowed within the command. The command is executed in the
starting directory.
Du kan også gjøre noe slikt som nedenfor.
find path_A -name "*AAA*" -print0 | xargs -0 -I {} mv {} path_B
Hvor,
-0
Hvis det er tomme mellomrom eller tegn (inkludert nye linjer), vil mange kommandoer ikke fungere. Dette alternativet tar hensyn til filnavn med
mellomrom.-I
Erstatt forekomster av replace-str i initial-arguments med navn lest fra standardinndata. Ikke-siterte blanktegn avslutter heller ikke
avslutter heller ikke inndataelementer; i stedet er skilletegnet ny linje
tegnet.**Testing
Jeg opprettet to kataloger som sourcedir
og destdir
. Nå opprettet jeg en rekke filer i sourcedir
som file1.bak
, file2.bak
og file3 med mellomrom.bak
.
Nå kjørte jeg kommandoen som,
find . -name "*.bak" -print0 | xargs -0 -I {} mv {} /destdir/
Når jeg nå kjører ls
i destdir
, kan jeg se at filene er flyttet fra sourcedir
til destdir
.
**Referanser
http://www.cyberciti.biz/faq/linux-unix-bsd-xargs-construct-argument-lists-utility/
-exec
er den beste måten å gjøre dette på. Hvis dette av en eller annen grunn ikke er mulig, kan du også lese resultatene i en løkke:
find path_A -name "*AAA*" -print0 |
while IFS= read -r -d $'\0' file; do mv "$file" path_B; done
Det er den sikre måten, og den kan håndtere filnavn som inneholder mellomrom, nye linjer eller andre merkelige tegn. En enklere metode, men som ikke fungerer med mindre filnavnene dine bare består av enkle alfanumeriske tegn, er
mv $(find path_A -name "*AAA*") path_B
Men bruk while-sløyfen.