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,...],
[........],
);
Я проигнорирую очевидные синтаксические ошибки в вашем коде и предположу, что вы хотите сохранить десять последних измененных файлов в каталоге ~/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
Никогда не рекомендуется использовать вывод 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
)-r
)файлов численно(-n
)только по первому полю(-k 1,1
)--т. е. по метке времени. 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}'
Я нашел другой ответ на проблему. Лучше всего использовать команду 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 указывает только один файл, т.е. самый старый файл.