What does an awk script expect its command line arguments to be? Why does it expect arg1 to be the input file?
awk
Правила, основанные на шаблонах, требуют ввода. Когда начинается обработка этих частей вашей программы, awk
начинает использовать аргументы в виде имен файлов (или стандартного ввода, если имена файлов не указаны ).
До этого шага вы можете делать все, что хотите, с заданными аргументами в блоке BEGIN
.
Думаю, эти небольшие примеры помогут вам начать работу:
$ cat a.awk
#!/usr/bin/awk -f
BEGIN {
i=1
while( i in ARGV )
print ARGV[i++]
}
a.awk
имеет только блок BEGIN
и не содержит правил, основанных на шаблонах. awk
не нуждается в файлах и поэтому не использует данные аргументы в качестве имен файлов:
$./a.awk poit --zort -troz narf
poit
--zort
-troz
narf
Вам решать, что с ними делать.
Если вы хотите, чтобы файлы, основанные на шаблонах, обрабатывались в качестве аргументов, вам необходимо удалить все аргументы, которые вы использовали в блоке BEGIN
:
$ cat b.awk
#!/usr/bin/awk -f
BEGIN {
if( ARGV[1] == "--tolower" ) { cmd = "tr A-Z a-z" ; delete ARGV[1] }
else if( ARGV[1] == "--toupper" ) { cmd = "tr a-z A-Z" ; delete ARGV[1] }
else cmd = "cat"
}
{
print | cmd
}
Пример работы без опции:
$./b.awk a.awk
#!/usr/bin/awk -f
BEGIN {
i=1
while( i in ARGV )
print ARGV[i++]
}
Пример работы с опцией --toupper
:
$./b.awk --toupper a.awk
#!/USR/BIN/AWK -F
BEGIN {
I=1
WHILE( I IN ARGV )
PRINT ARGV[I++]
}
Следуя вашим четырем шагам (игнорируя шаги "получить список...", так как они не нужны):
#!/bin/bash
topdir=some/directory/path
find "$topdir" -type f -name '*.gif' -exec sh -c '
for gifpath do
convert "$gifpath" "${gifpath%.gif}.png"
done' sh {} +
find "$topdir" -type f -name '*.png' -exec optipng {} \;
Сначала будут найдены все обычные файлы, имена которых заканчиваются на .gif
в пределах или ниже $topdir
, и преобразованы они в изображения PNG.
Затем он таким же образом находит все PNG-изображения и выполняет optipng
для каждой заметки (, что я ничего не знаю об этой команде, поэтому здесь я просто предполагаю ). Второй find
также найдет изображения в формате PNG, которые, возможно, существовали до запуска скрипта.
Если вы хотите запустить optipng
только для вновь созданных изображений PNG, используйте одинfind
:
find "$topdir" -type f -name '*.gif' -exec sh -c '
for gifpath do
pngpath=${gifpath%.gif}.png
convert "$gifpath" "$pngpath"
optipng "$pngpath"
done' sh {} +
Связанные:Понимание опции -exec команды `find`
Или, используя **
в bash
для рекурсивного сопоставления по$topdir
:
#!/bin/bash
topdir=some/directory/path
shopt -s globstar nullglob dotglob
for gifpath in "$topdir"/**/*.gif; do
if [ -f "$gifpath" ]; then
pngpath=${gifpath%.gif}.png
convert "$gifpath" "$pngpath"
optipng "$pngpath"
fi
done
В каждом фрагменте кода вышекоманда optipng
не будет выполняться до завершения команды convert
. Если это по-прежнему вызывает у вас проблемы того же характера, что и вы описываете (, изображения PNG недоступны после convert
), тогда я буду искать сообщения об ошибках, описывающие, что пошло не так.
Кто-то порекомендовал команду синхронизации, которая заставила бы систему очистить все кэши, а затем избежать незавершенных операций с дисками.
Но этот странный баг исчез. Мое предположение :синтаксическая причуда с моей стороны не обнаружена. Тем не менее, спасибо за помощь, а вот как это выглядит сейчас:
#!/bin/bash
clear
mapfile -t tab < <(jq -r '.[] |.' img_folders_to_optimize.json)
printf '%s\n' "${tab[@]}" | while read -r folder; do
echo "dossier à traiter : $folder"
cd "$folder" || exit
# GIF
for filepath in *.gif; do
echo "GIF : $filepath"
nb_frames=$(identify -format %n "$filepath")
if [ "$nb_frames" != 1 ]; then
echo "animated"
else
echo "convert to png"
filepath_png=${filepath/\.gif/.png}
convert "$filepath" "$filepath_png" &>/dev/null
echo "converted"
fi
done
# PNG
for filepath in *.png; do
echo "PNG : $filepath"
echo "optimize"
optipng -o7 -strip all "$filepath" &>/dev/null
echo "convert lossless to webp"
filepath_webp=${filepath/\.png/.webp}
cwebp -lossless "$filepath" -o "$filepath_webp" &>/dev/null
done
# JPG
for filepath in *.jpg; do
echo "JPG : $filepath"
echo "optimize"
mogrify -quality 70 "$filepath"
echo "convert lossy to webp"
filepath_webp=${filepath/\.jpg/.webp}
cwebp -q 50 -m 4 -mt "$filepath" -o "$filepath_webp"
done
echo "dossier traité"
done