Удалить новую строку, пробел из файла

Это кажется плохим:

hostname: Name or service not known
dpkg: error processing package ssmtp (--configure):
 subprocess installed post-installation script returned error exit status 1

имя хоста используется в скрипте postinst (описывается в руководстве Debian для сопровождающих пакетов - ссылка ) не работает.

Как я проверял, упомянутый пакет ssmtp в версии 2.64-8 (amd64) имеет следующий скрипт:

#!/bin/sh

set -e

if test -L /usr/doc/ssmtp
then
    rm -f /usr/doc/ssmtp 2>/dev/null || true
fi

. /usr/share/debconf/confmodule

db_get ssmtp/root
root="$RET"

db_get ssmtp/mailhub
mailhub="${RET:-mail}"

db_get ssmtp/port
port="$RET"

db_get ssmtp/hostname
hostname="${RET:-`hostname --fqdn`}"

db_get ssmtp/rewritedomain
rewritedomain="$RET"

if test -s /etc/mailname
then
    :
else
    test -n "$hostname" && MailName="$hostname"
    test -n "$rewritedomain" && MailName="$rewritedomain"

    touch /etc/mailname
    chmod 644 /etc/mailname
    echo "$MailName" > /etc/mailname
fi

db_get ssmtp/fromoverride
test "$RET" = "true" && FromOverride=YES

test -d /etc/ssmtp || exit 1

if test -s /etc/ssmtp/ssmtp.conf
then
    if test "$port" = "25" -o -z "$port"
    then
        :
    else
        mailhub=${mailhub}:$port
    fi
    test -z "$FromOverride" && FromOverride=NO

    touch /etc/ssmtp/ssmtp.conf.tmp
    chmod 644 /etc/ssmtp/ssmtp.conf.tmp

    sed "s/^root=.*/root=$root/;s/^mailhub=.*/mailhub=$mailhub/;s/^rewriteDomain=.*/rewriteDomain=$rewritedomain/;s/^hostname=.*/hostname=$hostname/;s/^FromLineOverride=.*/FromLineOverride=$FromOverride/;s/^#FromLineOverride=.*/FromLineOverride=$FromOverride/" /etc/ssmtp/ssmtp.conf > /etc/ssmtp/ssmtp.conf.tmp
    mv -f /etc/ssmtp/ssmtp.conf.tmp /etc/ssmtp/ssmtp.conf
else
    touch /etc/ssmtp/ssmtp.conf
    chmod 644 /etc/ssmtp/ssmtp.conf

    exec 1>/etc/ssmtp/ssmtp.conf

    echo "#"
    echo "# Config file for sSMTP sendmail"
    echo "#"
    echo "# The person who gets all mail for userids < 1000"
    echo "# Make this empty to disable rewriting."
    echo "root=$root"
    echo
    echo "# The place where the mail goes. The actual machine name is required no "
    echo "# MX records are consulted. Commonly mailhosts are named mail.domain.com"
    if test "$port" = "25" -o -z "$port"
    then
        echo "mailhub=$mailhub"
    else
        echo "mailhub=${mailhub}:$port"
    fi
    echo
    echo "# Where will the mail seem to come from?"
    test -z "$rewritedomain" && echo -n "#"
    echo "rewriteDomain=$rewritedomain"
    echo ""
    echo "# The full hostname"
    echo "hostname=$hostname"
    echo
    echo "# Are users allowed to set their own From: address?"
    echo "# YES - Allow the user to specify their own From: address"
    echo "# NO - Use the system generated From: address"
    test -z "$FromOverride" && echo -n "#"
    echo "FromLineOverride=YES"
fi

# Program End
exit 0

Самый важный из них:

hostname="${RET:-`hostname --fqdn`}"

Как уже упоминалось, имя хоста - fqdn не удалось. Пожалуйста, проверьте, существует ли:

  • команда
  • какая команда имя хоста --fqdn return

0
11.04.2019, 01:41
2 ответа

Вам не нужно -name '*', так как вы хотите обработать каждый файл(*в любом случае соответствует каждому файлу, так что это не имеет никакого значения ). Однако вы можете захотеть -type fобрабатывать только обычные файлы (, а не каталоги и т. д.)

Чтобы удалить все, что не является буквой, вы можете использовать

tr -cd '[:alpha:]' <file

-cдополняет заданный набор символов, а [:alpha:]соответствует только буквенным символам. -dдает указание trудалить совпадающие символы.

Таким образом, вы можете выполнить следующую команду:

tr -cd '[:alpha:]' <file | wc -m

для каждого файла.

Поскольку это слишком сложно для findвыполнения напрямую, вам придется использовать -строчный скрипт:

find. -type f -exec sh -c '
    for pathname do
        tr -cd "[:alpha:]" <"$pathname" | wc -m
    done' sh {} +

Здесь скрипт в строке -sh -cполучит пакеты путей к файлам в качестве аргументов из find. Конвейер будет выполняться для каждого файла.

2
28.01.2020, 02:15

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

Теперь, чтобы удалить все символы, кроме алфавитных (любого алфавита ), как сказал @Kusalanada, POSIXly, вы должны использовать tr -cd '[:alpha:]'.

К сожалению, в некоторых trреализациях, включая GNU tr, это не работает для многобайтовых -символов. В локалях UTF -8 это означает все символы, кроме ASCII.

В системах GNU вы можете использовать GNU awkили GNU sed, которые поддерживают многобайтовые символы:

<file sed 's/[^[:alpha:]]//g' | tr -d '\n'

<file awk -v ORS= '{gsub(/[^[:alpha:]]/, ""); print}'

Этот синтаксис не является специфичным для GNU -, но вы найдете некоторые реализации, не относящиеся к -GNU sed/ awk, которые не поддерживают многобайтовые символы. Помните, что GNU sed/ awkпо крайней мере не удалит последовательности байтов, которые не образуют допустимых символов (, как вывод printf 'à b \200\n'в локали UTF -8 ).

С помощью uconvиз проекта ICU вы можете сделать:

<file uconv -i -x '[^[:Letter:]]>;'

Где -iуказывает uconvпропустить ввод, который не может быть декодирован.

Но это работает только для данных UTF -8. Обратите внимание, что он использует свойства символов Unicode (некоторую версию Unicode ), в отличие от того, что ваш язык определяет, что в алфавитном порядке, а что нет.

С GNU grepвы можете использовать:

<file grep -o '[:alpha:]' | tr -d '\n'

Или при сборке с поддержкой PCRE (с использованием свойств Unicode):

<file grep -Po '\pL' | tr -d '\n'

В GNU awkдругим способом пропустить неверный ввод является использованиеRS:

<file gawk -v RS='[[:alpha:]]' -v ORS= '{print RT}'

Чтобы изменить файлы в месте -, вы можете использовать gawkмодуль inplace:

gawk -i inplace gawk -v RS='[[:alpha:]]' -v ORS= '{print RT}' file
4
28.01.2020, 02:15

Теги

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