почему скрипт tcsh блокирует специальные символы внутри файла, например. #{ в строке выдается ошибка "}"

Сложный бит в этом вопросе на самом деле заключается в форматировании вывода в столбцах.

Предположим, у вас есть файл с|-разделенными столбцами, и вы хотите добавить к нему новый столбец. Если вы используете pasteкак

paste -d '|' file newdata

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

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

BEGIN { OFS = FS }

FNR == 1 {
    # We assume that all lines have the same number of columns.
    nf = NF
}

{
    # Read new column from stdin (clear col if failing).
    if ((getline col <"/dev/stdin") != 1)
        col = ""

    # Add new column (possibly empty) and print.
    $(nf + 1) = col
    print
}

END {
    # We only need to do something here if the new column
    # data is longer than the existing data.

    $0 = "" # Clear current line.

    # Add data from stdin until there is no more to read.
    while ((getline col <"/dev/stdin") == 1) {
        $(nf + 1) = col
        print
    }
}

Хорошо, давайте воспользуемся этим, чтобы создать небольшой сценарий оболочки, который будет подключаться по SSH к ряду серверов, имена которых перечислены в файле, и извлекать пользователей из файла /etc/passwdна каждом:

#!/bin/sh

outfile=/tmp/outfile
serverlist=servers.list

tmpfile=$( mktemp )

while read -r server; do
    ssh -n "$server" cat /etc/passwd |
    cut -d : -f 1 |
    {
        echo '****************'
        printf '%s\n\n' "$server"
        cat
    } |
    awk -F '|' -f append_column.awk "$tmpfile" >"$outfile"
    cp "$outfile" "$tmpfile"
done <"$serverlist"

awk -F '|' '{ for (i=1; i<=NF; ++i) $i = sprintf("%-20s", $i); print }' "$tmpfile" >"$outfile"

rm -f "$tmpfile"

Здесь append_column.awk— это файл, состоящий из программы awkв верхней части этого ответа.

Сценарий считывает файл $serverlistв цикле и вызывает ssh -n, чтобы получить файл /etc/passwd. Параметр -nнеобходим с ssh, так как в противном случае sshбудет считываться из того же файла $serverlistпри повторении цикла.

Имена пользователей извлекаются с помощью cut.

Бит {... }выводит короткий заголовок, а затем передает имена пользователей без изменений через вызов cat.

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

После окончания цикла файл в $tmpfile(, а также $outputна самом деле )будет содержать нужные данные в виде|-полей с разделителями. Чтобы очистить это,мы вызываем еще один сценарий Short in -line awk, который форматирует столбцы выходного файла с выравниванием по левому краю -и текстовыми полями длиной 20 символов.

0
28.06.2020, 00:21
1 ответ

Спасибо @Mark Plotnick за ответ:

"`head -$i input.txt | tail -1`"
echo $each_line:q

это сработало и не показывало отсутствующую } ошибку. я смог переместить его в переменную и также использовать для сравнения строк.

0
18.03.2021, 23:23

Теги

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