Сценарий оболочки для перемещения самого старого файла из одного каталога в другой

perl -lane '
   $F[$_] > $A[$F[0]-1][$_] and $A[$F[0]-1][$_] = $F[$_] for 1.. $#F}{
   print 1+$_, "@{$A[$_]}" for grep defined $A[$_], 0.. $#A
' ifile.dat

Результаты

1 40 76
2 20 98
3 34 33
4 50 100
5 3 46

Рабочий

Data structure involved is an `LoL` (list of lists) assuming that the
column 1 data is nonnegative.

@A = (
   [column_2_max_for_idx1, column_3_max_for_idx1, column_4_max_for_idx1,...],
   [........],
);
0
27.09.2019, 14:16
3 ответа

Я проигнорирую очевидные синтаксические ошибки в вашем коде и предположу, что вы хотите сохранить десять последних измененных файлов в каталоге ~/work. Я также предполагаю, что у вас есть оболочка zsh.

Следующий сценарий оболочки zshперемещает все файлы, кроме десяти последних измененных, из ~/workв ~/regular_archieve.

#!/bin/zsh

mv -i $HOME/work/*(.om[11,-1]) $HOME/regular_archieve

Единственная команда в сценарии оставляет десять последних измененных файлов в ~/work, а остальные перемещает в ~/regular_archieve. Это делается с помощью mvи специального шаблона zsh-. Шаблон *(.om[11,-1])будет расширяться до обычных файлов, которые необходимо переместить (никакие каталоги не будут соответствовать ). Это om, который сортирует файлы по метке времени модификации, и [11,-1], который выбирает имя файла с 11 до самого старого файла в этом отсортированном списке. Точка в начале квалификатора glob.om[11,-1]означает, что glob соответствует только обычным файлам.

Если у вас может быть много тысяч файлов в каталоге, это может привести к ошибке «Слишком длинный список аргументов». В этом случае перемещайте файлы по отдельности, используя цикл :

.
#!/bin/zsh

for pathname in $HOME/work/*(.om[11,-1]); do
    mv -i $pathname $HOME/regular_archieve
done
0
28.01.2020, 02:39

Никогда не рекомендуется использовать вывод lsдля чего-либо, кроме просмотра в терминале. См. Почему не разборls(и что делать вместо )? . Вместо этого используйтеfind:

find /home/balaji/work/ -type f -printf '%C@\t%p\0' |
  sort -z -k1,1 -r -n |
  cut -z -f2 |
  head -z -n 10 | 
  xargs -0r echo mv -t /home/balaji/regular_archive/

Для этого требуются версии GNU find, sort, cut, tailиxargs(или, по крайней мере, другие их версии, поддерживающие параметр -zдля разделителей записей NUL ). ].

  • findиспользует -printf '%C@\t%p\0'для перечисления последних -измененных меток времени (%C@, в секундах с начала эпохи 1970 -01 -01 00 :00 :00 )и имен файлов(%p)всех обычных файлов. Поля разделены одной вкладкой (\t), а каждая запись разделена символом NUL (\0)
  • .
  • вывод find направляется в sort для обратной сортировки(-r)файлов численно(-n)только по первому полю(-k 1,1)--т. е. по метке времени.
  • вывод sort направляется в cut для удаления поля метки времени (он нам больше не нужен после того, как мы закончили сортировку)
  • вывод cut направляется в headдля получения первых десяти записей
  • и, наконец, выходные данные head передаются в xargsдля выполнения команды mv. При этом используется расширение GNU -tдля mv, так что целевой каталог может быть указан перед именами файлов.

На самом деле, это работает echo mv, а не mv, так что это пробный -запуск. Избавьтесь от echo, если вы уверены, что он будет делать то, что вам нужно.

Примечание :Это будет работать с любыми именами файлов, независимо от того, какие странные и раздражающие символы они могут содержать (, например. пробелы, новые строки, метасимволы оболочки и т. д. ). Кроме того, команда fileимеет много других опций, которые можно использовать для уточнения критериев поиска.


Если у вас старая версия GNU coreutils (, то есть < версии 8.25 ), ни cut, ни head, ни tailне будут иметь опции -z. Вместо этого вы можете использовать awk. например.

find /home/balaji/work/ -type f -printf '%C@\t%p\0' |
  sort -z -k1,1 -r -n |
  awk -F '\t' 'BEGIN {RS=ORS="\0"}; NR<=10 { $1=""; $0=$0; $1=$1 ; print }' |
  xargs -0r echo mv -t /home/balaji/regular_archive/

В качестве альтернативы вы можете использовать perlвместоawk:

 perl -F'\t' -0lane 'if ($. <= 10) {delete $F[0]; print @F}'
1
28.01.2020, 02:39

Я нашел другой ответ на проблему. Лучше всего использовать команду find вместо команды ls . Это поможет найти самый старый файл и может использовать команду mv для перехода в другой каталог.

mv $(find /home/balaji/work/ -type f -printf '%T+ %p\n' | sort | head -1) /home/balaji/regular_archieve

find– Поиск файлов в иерархии каталогов.

/home/balaji/work/– Поиск местоположения.

/home/balaji/regular_archieve/– Местоположение цели.

type -f– поиск только в обычных файлах.

-printf ‘%T+ %p\n’— печатает дату и время последней модификации файла, разделенные символом +. (Напр. 2015 -07 -22+13 :42 :40.0000000000 ). Здесь %p указывает имя файла. \n указывает на новую строку.

sort | head -n 1— Команда sort сортирует выходные данные и отправляет выходные данные команде head для отображения самого старого файла. Здесь -n 1 указывает только один файл, т.е. самый старый файл.

0
28.01.2020, 02:39

Теги

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