Копировать файлы в новый каталог только в том случае, если имя файла находится в массиве

Смотрите на это названное сообщение в блоге: Как К: 2 Метода Для Изменения TimeZone в Linux.

Дистрибутивы Red Hat

При использовании распределения, такого как Red Hat затем подход копирования файла был бы главным образом приемлем.

Примечание: При поиске агностического дистрибутивом решения это также работает над Debian, хотя существуют более простые подходы ниже, если Вы только должны быть обеспокоены машинами Debian.

$ ls /usr/share/zoneinfo/
Africa/      CET          Etc/         Hongkong     Kwajalein    Pacific/     ROK          zone.tab
America/     Chile/       Europe/      HST          Libya        Poland       Singapore    Zulu
Antarctica/  CST6CDT      GB           Iceland      MET          Portugal     Turkey       
Arctic/      Cuba         GB-Eire      Indian/      Mexico/      posix/       UCT          
Asia/        EET          GMT          Iran         MST          posixrules   Universal    
Atlantic/    Egypt        GMT0         iso3166.tab  MST7MDT      PRC          US/          
Australia/   Eire         GMT-0        Israel       Navajo       PST8PDT      UTC          
Brazil/      EST          GMT+0        Jamaica      NZ           right/       WET          
Canada/      EST5EDT      Greenwich    Japan        NZ-CHAT      ROC          W-SU         

Я рекомендовал бы связаться с ним вместо копирования как бы то ни было.

$ sudo unlink /etc/localtime 
$ sudo ln -s /usr/share/zoneinfo/Etc/GMT+6 /etc/localtime

Теперь дата показывает другой часовой пояс:

$ date -u
Thu Jan 23 05:40:31 UTC 2014

$ date 
Wed Jan 22 23:40:38 GMT+6 2014

Дистрибутивы Ubuntu/Debian

Для изменения часового пояса на любом из этих дистрибутивов, можно использовать эту команду:

$ sudo dpkg-reconfigure tzdata

    ss #1

$ sudo dpkg-reconfigure tzdata

Current default time zone: 'Etc/GMT-6'
Local time is now:      Thu Jan 23 11:52:16 GMT-6 2014.
Universal Time is now:  Thu Jan 23 05:52:16 UTC 2014.

Теперь, когда мы проверяем его:

$ date -u
Thu Jan 23 05:53:32 UTC 2014

$ date 
Thu Jan 23 11:53:33 GMT-6 2014

Примечание: Существует также эта опция в Ubuntu 14.04 и выше с единственной командой (источник: Спросите Ubuntu - устанавливающий часовой пояс от терминала):

$ sudo timedatectl set-timezone Etc/GMT-6

На использовании "Etc/GMT+6"

выборка из ответа @MattJohnson на ТАК

Зоны как Etc/GMT+6 намеренно инвертируются для назад совместимости со стандартами POSIX. См. комментарии в этом файле.

Вы почти никогда не должны должны быть использовать эти зоны. Вместо этого необходимо использовать полностью именованный часовой пояс как America/New_York или Europe/London или независимо от того, что подходит для Вашего местоположения. Обратитесь к списку здесь.

2
17.10.2015, 18:53
4 ответа
$ find sourcedir -type f -name 'file?.pdf' -exec cp {} targetdir \;

должны соответствовать только тем файлам, которые соответствуют этому шаблону.

1
27.01.2020, 21:56

Если я правильно вас понял, в каждом из ваших каталогов есть только один файл, и вы хотите переместить этот файл, если он есть в вашем списке. Если это так, вы можете сделать:

while read -r file; do cp sourcedir/*/"$file" targetdir; done < list.txt

Если вам также нужно скопировать каталоги, вы можете прочитать файлы, уберите расширение файла , чтобы получить имя каталога, и скопируйте его:

while read -r file; do cp -r sourcedir/"${file%.*}" targetdir; done < list.txt
0
27.01.2020, 21:56

Если у вас есть имена файлов, сохраненные в массиве, и ни одно из них не содержит | (поскольку это нужно экранировать, но не стоит беспокоиться - см. альтернативу ниже), вы можете просто объединить элементы массива и использовать результат как glob:

myarr=( file1 file2 ... fileN )
lst=${(j:|:)myarr}
cp -v -- **/($~lst) targetdir

например. с этими файлами в случайных местах в моем /tmp:

caxZN.gif
e8ApF.gif
div2k.js.lzo
cmp2jz.ini

и их именами, сохраненными в массиве, вот результат:

cp -v -- **/($~lst) targetdir
‘tmp/div2k.js.lzo’ -> ‘targetdir/div2k.js.lzo’
‘tmp/other dir/e8ApF.gif’ -> ‘targetdir/e8ApF.gif’
‘tmp/other dir/one two/cmp2jz.ini’ -> ‘targetdir/cmp2jz.ini’
‘tmp/some dir/caxZN.gif’ -> ‘targetdir/caxZN.gif’

В качестве альтернативы, на этот раз предполагая, что они перечислены в файле, по одному имени файла в строке, вы можете считать строки в массив и затем использовать glob qualifiers/estring и modifiers для glob/select только имена файлов в вашем массиве:

mylist=(${(f)"$(<list_of_files)"})
cp -- **/*(.e_'(($mylist[(Ie)$REPLY:t]))'_) targetdir

практически . выбирает только обычные файлы (добавьте D, если ваш список содержит dotfiles), а e_'expression'_ возвращает только те имена файлов, для которых expression истинно, в данном случае, если их basename ($REPLY: t) является элементом массива mylist, например. g.:

print -rl -- **/*(.e_'(($mylist[(Ie)$REPLY:t]))'_)
tmp/div2k.js.lzo
tmp/other dir/e8ApF.gif
tmp/other dir/one two/cmp2jz.ini
tmp/some dir/caxZN.gif

Конечно, все вышесказанное предполагает zsh.
В любом случае, ваше собственное решение также работает, если вы потратите время на написание имен файлов и передадите правильные опции в find, например,

find . -type f \( -name caxZN.gif -o -name e8ApF.gif -o -name div2k.js.lzo -o -name cmp2jz.ini \) -exec cp -- {} targetdir \;
2
27.01.2020, 21:56

] Прежде всего, вот образец дерева, который я создал:

{   pwd
    for   d in ./*/
    do    cd "$d"
          printf '\t%s\n' "${d#??}"
          printf '\t\t%s\n' *
          cd ..
    done
}

/tmp/top
        another file/
                another file.pdf
        fileA/
                fileA.pdf
        otherdir/
                1
                2
                3
        stillanother4544file/
                stillanother4544file.pdf

Очевидно, что вам не нужно ничего делать - я создал дерево, которое отражает ваше примерное дерево, и просто добавил несколько выбросов.

Но вот что я рекомендую вам сделать:

pax -rwis'|^./\([^/]*\)/\(\1\....\)$|\2|' -s'|.*||' . ../tgt

Это вызывает стандартную POSIX утилиту pax в -r ead / -w rite mode - режим прямого копирования, в основном. В режиме копирования pax не создает архив tar , как обычно в режиме -w rite, а вместо этого напрямую копирует все файлы, найденные в его ] [... шаблон ...] аргумент [s] - здесь только . для дерева с корнем в текущем каталоге - и / или имена, которые оно читает на своем стандартном вводе (в данном случае пусто) - в каталог, названный его последним аргументом, который находится здесь ../ tgt .

Я знаю, что вы не хотите перемещать все дерево. Многое из этого решается с помощью аргументов -s ubstitution. Вы можете переименовывать выходные файлы на основе операторов в стиле регулярного выражения sed , как это делаю я здесь. Я использую два оператора -s ubstitution. Первый переименовывает все входные совпадения для:

./dirname/samename.???

... в ...

samename.???

... на выходе, тем самым сглаживая выходное дерево, чтобы все скопированные файлы помещались непосредственно в ../ tgt . Если вы предпочитаете оставить ./ dirname / родительские каталоги для каждого из них вы можете заменить часть \ 2 первого -s ubstitution только на и .

После того, как имя файла было успешно сопоставлено и изменено с помощью pax -s ubstitution, оно не будет повторяться ни для каких оставшихся аргументов -s ubstitution, и только для этих файлов которые еще не могут соответствовать, пробуются для оставшихся регулярных выражений переименования. Это означает, что все файлы, расположенные в текущем каталоге с именами пути, соответствующими типу:

./dirname/samename.???

... успешно выбраны и удаляются из всех компонентов, кроме последних, с помощью первого оператора -s ubstitution и всех другие файлы, расположенные в текущем каталоге, полностью заменяются второй заменой -s |. * || -s . Это потому, что pax удаляет из своего списка обработки любое имя файла, заменяющее пустую строку.

После того, как pax обработал все это, у него есть последняя обязанность, которую нужно выполнить, прежде чем он сможет фактически скопировать выбранные файлы - и это вариант интерактивного переименования -i , который я указано, и я думаю, что это, вероятно, прямо в вашем переулке.

Из man pax :

-i

  • Интерактивное переименование файлов или членов архива. Для каждого элемента архива, соответствующего операнду шаблона , или каждого файла, соответствующего файловому операнду, pax предложит / dev / tty указать имя файла, его файловый режим и время его модификации. pax затем прочитает строку из / dev / tty . Если эта строка пуста, элемент файла или архива пропускается. Если эта строка состоит из одной точки, файл или элемент архива обрабатывается без изменения его имени. В противном случае его имя заменяется содержимым строки. pax немедленно завершит работу с ненулевым статусом выхода, если EOF обнаружен при чтении ответа или если / dev / tty не может быть открыт для чтения и записи .

ATTENTION: pax interactive file rename operation.
-rw-r--r-- Oct 17 04:30 stillanother4544file.pdf
Input new name, or a "." to keep the old name, or a "return" to skip this file.
Input > .
Processing continues, name unchanged.

ATTENTION: pax interactive file rename operation.
-rw-r--r-- Oct 17 04:30 another file.pdf
Input new name, or a "." to keep the old name, or a "return" to skip this file.
Input >
Skipping file.

ATTENTION: pax interactive file rename operation.
-rw-r--r-- Oct 17 04:30 fileA.pdf
Input new name, or a "." to keep the old name, or a "return" to skip this file.
Input > .
Processing continues, name unchanged.

Таким образом, из шести файлов в текущем каталоге только эти три попадают в запросы интерактивного переименования -i , а из этих трех только два попадают в ../ tgt :

ls -l ../tgt

-rw-r--r-- 1 mikeserv mikeserv 0 Oct 17 04:30 fileA.pdf
-rw-r--r-- 1 mikeserv mikeserv 0 Oct 17 04:30 stillanother4544file.pdf
2
27.01.2020, 21:56

Теги

Похожие вопросы