Для обновления файла на месте sed
лучше подходит, чем awk, потому что:
- Вам не нужна последняя версия, более старые версии тоже могут это сделать
- Может работать как с GNU, так и с BSD -> более переносимым
Но сначала, чтобы разбить имя файла на его части, вам не нужен дополнительный процесс, встроенный в read
это тоже. Из ваших примеров нам нужно извлечь номера года, месяца, дня, недели, строку квартала и строку названия дня недели:
2019-10-18-42-IV-Friday.md
2019-10-18-42-IV-Saturday.md
2019-10-18-42-IV-Sunday.md
2019-10-18-43-43-IV-Monday.md
2019-10-18-42-IV Tuesday.md
Для первых 3 строк это простое выражение будет работать:
IFS=-. read year month day week q dayname rest <<< "$filename"
В последней строке перед именем дня недели вместо -
стоит пробел, но это легко исправить:
IFS='-. ' read year month day week q dayname rest <<< "$filename"
Строку 4 сложнее исправить, поскольку она имеетразное количество полей. Чтобы обработать дополнительное поле, мы должны добавить дополнительный переменный член:
IFS='-. ' read year month day week q dayname ext rest <<< "$filename"
И затем, если мы можем предположить, что второй 43
в этой строке можно игнорировать, и мы можем просто сдвинуть аргументы,тогда мы используем условное значение $ext
. То есть для большинства строк значение ext
будет md
(расширение файла). Если значение отличается, это означает, что у нас есть дополнительное поле, и мы должны сдвинуть значения:
if [[ $ext != "md" ]; then
q=$dayname
dayname=$ext
fi
Теперь мы можем использовать переменные для форматирования строки, которую вы хотите вставить в файл:
line="Today is $dayname, the $day.$month.$year, Kw $week, in the $q. Quarter."
Наконец, мы можем сформулировать оператор sed
, например, чтобы добавить нашу пользовательскую отформатированную строку после первой, в идеале таким образом, чтобы работать как с GNU, так и с BSD-вариантами sed
.
Это будет работать одинаково с версиями GNU и BSD:
sed -i.bak -e "1 a\\"$'\n'"$line"$'\n' "$filename" && rm *.bak
Обратите внимание, что созданы .bak
файлы резервных копий, которые необходимо удалить вручную.
Если вы неЕсли вы не хотите создавать файлы резервных копий, то, боюсь, вам нужно использовать немного другой формат для разновидностей GNU и BSD:
# GNU
sed -i'' -e "1 a\\"$'\n'"$line"$'\n' "$filename"
# BSD
sed -i '' -e "1 a\\"$'\n'"$line"$'\n' "$filename"
На самом деле, если вам требуется только поддержка разновидности GNU, тогда более простая форматоже будет работать:
sed -i'' "1 a$line" "$filename"
Все это можно объединить в цикл for filename in *.md; do ...; done
.