Как добавить заголовок к нескольким файлам с помощью awk

Мне просто нужно было выйти из системы и снова войти (только один раз )после создания файла конфигурации i3 моего пользовательского каталога, прежде чем i3 подхватит его.

PS :Вы можете проверить, какой файл конфигурации i3 вы используете, с помощью i3 --moreversion.

0
14.11.2021, 14:29
3 ответа

Вот модифицированная версия, которая у меня работает:

#!/bin/bash

header=$1
shift

for file in $@; do 
    awk -v HEADER="$header" 'BEGIN{print HEADER} {print}' "$file" > "$file".new
done

Я пытался использовать {print > [FILE].new}внутри выражения awk, но это не сработало. Он только что напечатал stdout. Возможно, потому что новые файлы не могут быть созданы в awk.

-2
14.11.2021, 15:26
#!/bin/sh

header=$1; shift

for pathname do
    { printf '%s\n' "$header"; cat -- "$pathname"; } >"$pathname.new"
done

Здесь нет реальной необходимости в awk, так как мы хотим объединить заголовок и содержимое старого файла. Мы делаем это, просто выводя строку заголовка с помощью printf, а затем используя catдля вывода содержимого файла. Мы перенаправляем вывод как printf, так и catв новый файл.

Хотите ли вы действительно сделать это с помощью awk, тогда либо перебирайте файлы, как в приведенном выше коде, либо позволяйте awkобрабатывать каждый файл без явного цикла оболочки.

Первый вариант с явным циклом оболочки:

#!/bin/sh

header=$1; shift

for pathname do
    header=$header awk 'BEGIN { print ENVIRON["header"] }; 1' "$pathname" >"$pathname.new"
done

Приведенное выше решение будет самым медленным вариантом из всех вариантов в этом ответе, поскольку оно вызывает awkодин раз для каждого файла.

Второй вариант без цикла оболочки (требует awk, который понимает BEGINFILE, как это делает GNU awk):

#!/bin/sh

header=$1; shift

header=$header awk '
    BEGINFILE { fname = FILENAME ".new"; print ENVIRON["header"] >(fname) }
    { print >(fname) }' "$@"

Третий вариант (переносимый вариант последней части кода):

#!/bin/sh

header=$1; shift

header=$header awk '
    FNR == 1 { fname = FILENAME ".new"; print ENVIRON["header"] >(fname) }
    { print >(fname) }' "$@"
0
14.11.2021, 15:38

Правильный способ сделать это, предполагая, что у вас нет пустых входных файлов, будет:

#!/usr/bin/env bash
header=$1 
shift 

awk -v header="$header" '
    FNR==1 { close(out); out=FILENAME ".new"; $0=header ORS $0 }
    { print > out }
' "$@"

Описанное выше будет работать с любым awk в любой оболочке на каждом компьютере с Unix. Если у вас могут быть пустые входные файлы, потребуется настройка.

0
14.11.2021, 16:13

Теги

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