Конечно, я бы использовал стандартный редактор UNIX (!):
for f in ENSG*
do
printf '1i\n\t%s\n.\nw\nq\n' "$f" | ed -s "$f"
done
Это отправляет небольшой скрипт команд на ed
, а именно:
i
)некоторый текст; текст передается через printf
как имя файла, которому предшествует табуляция(\t
).
)сохраните файл на диск(w
)и закройте(q
)Если действительно количество файлов превышает лимит строки команды -, вы можете использовать команду find
; отрегулируйте параметры (начальные каталоги, имена файлов и т. д. )по мере необходимости:
find. -name 'ENSG*' -exec sh -c 'printf "1i\n\t%s\\n.\nw\nq\n" "$1" | ed -s "$1" ' findsh {} \;
Основное решение такое же, но в оболочке того, что я называю «оболочкой поиска»,--find
выполняется sh -c...
для каждого (единственного )совпадающего имени файла; строка findsh
является заглушкой для $0
, и имя файла передается этой оболочке вместо фигурных скобок {}
.Тогда сама оболочка имеет имя файла в качестве параметра $1
, так что это то, что используют команды printf
и ed
.
Обратите внимание, что -size +100M
, где этот суффикс M
не является стандартным расширением -, выбирает файлы, размер которых строго превышает 100 МБ, 104 857 600 байт, а не 100 МБ (100 000 000 байт ). Для размеров (строго )больше 100 МБ вам потребуется -size +100000000c
(, который является стандартным ).
-mtime +20
предназначен для файлов, возраст которых составляет 21 день¹ ровно (или был с точностью до наносекунды на момент вызова find
)или старше. Вам нужно -mtime +19
для файлов старше 20 дней (по крайней мере в POSIX-совместимых реализациях find
, не все в этом отношении ).
Предполагая, что вы находитесь в оболочке типа Bourne -, отличной от zsh
, оставлять это $HOME
без кавычек не имеет смысла, так как нет смысла вызывать здесь split+glob. В оболочках POSIX вы также можете использовать ~
вместо "$HOME"
.
zip
— не очень Unixy-команда.По умолчанию он сам расширяет подстановочные знаки, поэтому, если у вас есть файл с именем *.txt
, zip -m '*.txt.zip' '*.txt'
фактически создаст zip-файл со всеми файлами txt
в каталоге. Ситуация может ухудшиться, например, если этот файл находится в каталоге с именем *
. Вы можете избежать этого с помощью флага -nw
или использовать более unix-команду, которая поддерживает этот старый формат zip, например bsdtar
.
Если вы сделаете find ~
, все пути, переданные в zip
, будут абсолютными путями, поэтому в итоге у вас будут zip-файлы, члены которых перечислены с их полными путями(home/you/dir/file.txt
... ). Вы можете использовать предикат BSD/GNU-execdir
find
или опцию -j
для zip
, чтобы избежать этого.
Обратите внимание, что не все реализации find
расширят {}
в {}.zip
, то есть когда {}
не является аргументом -exec
. В тех случаях, когда это не так, вам нужно прибегнуть к вызову sh
с помощью -exec sh -c 'zip -nw -m "$1.zip" -- "$1"' sh {} ';'
.
Для сопоставления имени файла используется предикат -name
. Вы можете использовать '(' -name '*.txt' -o -name '*.TXT' ')'
для сопоставления с файлами txt
или TXT
или -name '*.[tT][xX][tT]'
или в некоторых реализациях find
-iname '*.txt'
, чтобы также включить Txt
, tXT
... файлы. В некоторых реализациях find
-name
требуется, чтобы имя файла было допустимым текстом в локали пользователя. Поскольку все символы .txtTXT
являются частью переносимого набора символов, вы можете установить языковой стандарт на C, чтобы гарантировать, что он всегда будет совпадать с файлами, которые заканчиваются на них, даже если остальная часть пути к файлу не является допустимым текстом в пользовательском коде. локаль.
Так:
LC_ALL=C find ~ '(' -name '*.txt' -o -name '*.TXT' ')' \
-type f \
-size +100000000c \
-mtime +19 \
-execdir zip -nw -m '{}.zip' -- '{}' ';'
Или используйте zsh
и:
for f (~/**/*.(txt|TXT)(ND.L+100000000m+19)) zip -j -nw -m $f.zip $f
Обратите внимание, что zip — это старый формат конца 80-х годов с плохой степенью сжатия по сегодняшним меркам. Его единственное достоинство в том, что это единственное сжатие (на самом деле, оно выполняет как архивацию, так и сжатие, в то время как вам нужен только последний здесь формат ), поддерживаемый из коробки в операционных системах Microsoft.
Здесь, если вам не нужна совместимость с операционными системами Microsoft,вы можете использовать более современные компрессоры, такие как xz
, bzip2
. Даже gzip
из начала 90-х годов, который использует тот же алгоритм сжатия, что и zip
, также даст вам лучшее уменьшение размера, поскольку он заботится только о сжатии. Все они также могут сжимать более одного файла за раз, что сделает процесс сжатия многих файлов более эффективным, поскольку вы сможете запускать компрессор меньше раз.
Например, вы можете сделать:
xz ~/**/*.(txt|TXT)(ND.L+100000000m+19)
Из оболочки zsh
для лучшего сжатия всех этих файлов одним вызовом xz
.
¹ дней здесь 86400 (24 × 60 × 60 )Unix-секунды, а не календарные дни, в которых изменения часов из-за перехода на летнее время не учитываются.