Jak przenieść (lub skopiować) wszystkie pliki do katalogu z tym samym prefiksem nazwy pliku?

9

Korzystanie z Bash

Powiedzmy, że mam kilka plików losowo umieszczonych w katalogu nadrzędnym. ~/srcChcę pobrać wszystkie pliki pasujące do określonego sufiksu i przenieść je (lub skopiować) do ~/distkatalogu.

Załóżmy w tym celu, że wszystkie nazwy plików mają następującą konwencję nazewnictwa:

<filename_prefix>.<filename_suffix>

Dowiedziałem się, że był to szybki sposób na pobranie wszystkich plików z określonym filename_suffixplikiem i umieszczenie go w folderze dist:

mkdir ~/dst
find source -name "*.xxx" -exec mv -i {} -t ~/dst \;

Teraz krok dalej ... jak mogę w tym przypadku użyć wyjścia find filenamei użyć filename_prefixdo wygenerowania katalogu o tej samej nazwie w, ~/dista następnie przeniesienie (lub skopiowanie) wszystkich plików z tym prefiksem do odpowiedniego katalogu?

mkdir ~/dst
find source -name "*.xrt,*.ini,*.moo" -exec mv -i {} -t ~/dst \;

Zasadniczo, jak zmienić powyższe polecenie (lub może użyć innego polecenia), aby utworzyć taką strukturę

(WYNIK)

~/dist/people/people.xrt
~/dist/games/games.xrt
~/dist/games/games.moo
~/dist/games/games.ini
~/dist/monkeys/monkeys.ini
~/dist/monkeys/monkeys.xrt

z takiego drzewa katalogów?

(WEJŚCIE)

~/src/xrt/people.xrt
~/src/xrt/games.xrt
~/src/conf/games.ini
~/src/pack/monkeys.xrt
~/src/e344/games.moo
~/src/e344/monkeys.moo
~/src/en-us/monkeys.ini
qodeninja
źródło

Odpowiedzi:

10

Piekło byłoby powiedzieć, findco robić w tym przypadku.

Lepiej użyj powłoki:

for i in **/*.{xrt,ini,moo}; do
  FILE=$(basename "$i")
  DIR=~/dst/${FILE%.*}
  echo mkdir -p -- "$DIR"
  echo mv -i -t "$DIR" -- "$i"
done

Użyj, shopt -s globstaraby **glob działał (lub użyj zsh!). I usuń echos później, jeśli polecenie wydrukuje to, co chcesz.

Stéphane Gimenez
źródło
używając bash czy to to samo?
qodeninja
@codeninja shopt -s globstar, zobacz moją edycję. Jeśli są tylko dwa poziomy, możesz użyć, */*.*a fragment kodu będzie działał w dowolnej powłoce.
Gilles „SO- przestań być zły”
2

oszukiwanie znaleźć wiersz poleceń:

find source -name "*.xrt,*.ini,*.moo" -exec env file={} bash -c 'base="$(basename "$file")";dir="dst/${base%.*}";mkdir -p "$dir";cp "$file" "$dir"' \;

właściwie obejście do wywoływania skryptu bash w find LOL.

= P

yuyichao
źródło
1
Zgadnij, co się stanie, jeśli istnieje plik o nazwie… happy rm -rf /! Ten rodzaj kodu zasługuje na -1.
Stéphane Gimenez,
Twoja edycja to za mało: powiedzmy, że kliknąłeś link i pobrałeś Yay" rm -rf / "Rox0r.avi, znowu jest jak problem…
Stéphane Gimenez
(I nie ma sposobu, aby ten rodzaj zamiany był bezpieczny).
Stéphane Gimenez,
1
Ach, może to zrobić inaczej. Wydaje się, że następujące prace: -exec bash -c 'command which uses "$1"' bash '{}' ';'. Cóż, i tak jest to zupełnie bezcelowe.
Stéphane Gimenez
1
@ StéphaneGimenez gotowe, bash nie jest jedyną rzeczą do użycia. LOL
yuyichao,