сценарий оболочки для изменения каталога на конечный путь - PullRequest
0 голосов
/ 13 марта 2019

Я использую Хвост, чтобы произошла ошибка в строках журнала, например:

tail -f syschecklog.log | grep "ERROR processEvent: /mnt/docs/"

, и это дает такие результаты:

01.lnxp.com 2019-03-13 07:10:24, 345 ERROR processEvent: /mnt/docs/003217899/cfo paid ¿ inv -inc 1234321

Итак, что я делаю вручную, так это изменяюпуть с использованием cd:

cd /mnt/docs/003217899/

Существует ли какой-либо сценарий для автоматического изменения каталога?Когда я запускаю другой ручной сценарий, чтобы изменить имена файлов для файлов, содержащихся в /003217899/, такие, как /003217899/, происходят много раз в день, и они меняются, поэтому мне нужен этот сценарий, чтобы автоматически отлавливать эти ошибки и изменятьзатем запустите сценарий изменения имени файла.

В дополнение к вышесказанному, в строке журнала есть еще одна подпапка с именем файла ошибок, например /mnt/docs/003217899/attch/fees ¿ to be paid.Как мы можем cd в этот каталог?

После изменения [Обновить]

 grep "ERROR processEvent: /mnt/docs/"  syschecklog.log | sed 's#.*ERROR processEvent: /mnt/docs/ \(/.*\)/.*#\1#' | while read -r DIR
   do
BASEDIR=${DIR%/*}
if [ "$BASEDIR" != /mnt/docs/ ]
then
    ( cd "$BASEDIR" && find  -type f  -exec touch {} + | python -c 'import os, re; [os.rename(i, re.sub(r"\?", "¿", i)) for i in os.listdir(".")]' )
fi
# end of code for additional requirement
( cd "$DIR" && find  -type f  -exec touch {} + | python -c 'import os, re; 
    [os.rename(i, re.sub(r"\?", "¿", i)) for i in os.listdir(".")]' )
    done

Результаты:

[результаты] [1]

Обновлен 3-й скрипт для renameFiles();

$ renameFiles()
> {
>     # The next line is copied unchanged from the question. This could be improved.
>     find  -type f  -exec touch {} + | python -c 'import os, re; [os.rename(i, re.sub(r"\?", "¿", i)) for i in os.listdir(".")]'
> }
$
$ # Two possible variants because the question was modified.
$ #
$ # To process the complete input file as it is now
$ #  grep "ERROR processEvent: /mnt/docs/"  syschecklog.log | ...
$ #
$ # To continuously follow the file
$ # tail -f /mnt/docs/syschecklog.log | grep "ERROR processEvent: /mnt/docs/" | ...
$
$ grep "ERROR processEvent: /mnt/docs/"  syschecklog.log | sed 's#.*ERROR processEvent: \(/.*\)/.*#\1#' | while read -r DIR
> do
>     # additional requirement from comment: if DIR is /mnt/docs/003217899/attch
>     # the script should be run both in .../003217899 and .../attch
>     BASEDIR=${DIR%/*}
>     if [ "$BASEDIR" != /mnt/docs/ ]
>     then
>         ( cd "$BASEDIR" && renameFiles)
>     fi
>     # end of code for additional requirement
>     ( cd "$DIR" && renameFiles)
> done
-bash: cd: /mnt/docs/001234579/Exp8888861¿_Applicant_Case_Conference_l (No such file or directory): No such file or directory
-bash: cd: /mnt/docs/001888579/¿_SENIOR_RESOLUTION_MANAGER_i(No such file or directory): No such file or directory
-bash: cd: /mnt/docs/001234579/Exp2222276¿18 from all and Treatments Inc. February 27_ 20199999(No such file or directory): No such file or directory

3-ий результат [3-й результат] [2]

     -bash: cd: /mnt/docs/001234579/Exp8888861¿_Applicant_Case_Conference_l (No such file or directory): No such file or directory
-bash: cd: /mnt/docs/001888579/¿_SENIOR_RESOLUTION_MANAGER_i(No such file or directory): No such file or directory
-bash: cd: /mnt/docs/001234579/Exp2222276¿18 from all and Treatments Inc. February 27_ 20199999(No such file or directory): No such file or directory
  • grep по вашему запросу;

    grep "ERROR processEvent: /mnt/docs/"  syschecklog.log
        01.lnxp.com 3    2019-03-14 07:04:30,446 ERROR processEvent: /mnt/docs/001111224/Exposure2178861/Email_from_LAT__18_009945_AABS¿__Summary_not_received12128050 (No such file or directory)
    01.lnxp.com 3    2019-03-14 07:05:13,137 ERROR processEvent: /mnt/docs/001567890/Coop_subro_question__TO__ZED_LANDERS_¿_SENIOR__Basse12130781 (No such file or directory)
    01.lnxp.com 3    2019-03-14 07:05:19,914 ERROR processEvent: /mnt/docs/001323289/Exposure2622276/OCF¿18 from All and                              Treatments Inc. February 27_ 201912129762 (No such file or directory)
    

Результаты Locale

$ locale
LANG=en_CA.UTF-8
LC_CTYPE="en_CA.UTF-8"
LC_NUMERIC="en_CA.UTF-8"
LC_TIME="en_CA.UTF-8"
LC_COLLATE="en_CA.UTF-8"
LC_MONETARY="en_CA.UTF-8"
LC_MESSAGES="en_CA.UTF-8"
LC_PAPER="en_CA.UTF-8"
LC_NAME="en_CA.UTF-8"
LC_ADDRESS="en_CA.UTF-8"
LC_TELEPHONE="en_CA.UTF-8"
LC_MEASUREMENT="en_CA.UTF-8"
LC_IDENTIFICATION="en_CA.UTF-8"
LC_ALL=

Результаты fgrep python yourscript |od -c -tx1

$ fgrep python invert.sh | od -c -tx1
0000000                   f   i   n   d           -   t   y   p   e
         20  20  20  20  66  69  6e  64  20  20  2d  74  79  70  65  20
0000020   f           -   e   x   e   c       t   o   u   c   h       {
         66  20  20  2d  65  78  65  63  20  74  6f  75  63  68  20  7b
0000040   }       +       |       p   y   t   h   o   n       -   c
         7d  20  2b  20  7c  20  70  79  74  68  6f  6e  20  2d  63  20
0000060   '   i   m   p   o   r   t       o   s   ,       r   e   ;
         27  69  6d  70  6f  72  74  20  6f  73  2c  20  72  65  3b  20
0000100   [   o   s   .   r   e   n   a   m   e   (   i   ,       r   e
         5b  6f  73  2e  72  65  6e  61  6d  65  28  69  2c  20  72  65
0000120   .   s   u   b   (   r   "   \   ?   "   ,       " 302 277   "
         2e  73  75  62  28  72  22  5c  3f  22  2c  20  22  c2  bf  22
0000140   ,       i   )   )       f   o   r       i       i   n       o
         2c  20  69  29  29  20  66  6f  72  20  69  20  69  6e  20  6f
0000160   s   .   l   i   s   t   d   i   r   (   "   .   "   )   ]   '
         73  2e  6c  69  73  74  64  69  72  28  22  2e  22  29  5d  27
0000200  \n
         0a
0000201

Мне нужно поменять каждое '?'в имени файла к «¿», как система создает «?»и он отображается как «¿», поэтому нужно изменить его на тот, где сервер может это понять!

Я обнаружил, что заглавная буква A в шляпе создается самой в системе, используя CAT

cat invert.sh
#!/bin/bash

renameFiles()
{
    find  -type f  -exec touch {} + | python -c 'import os, re; [os.rename(i, re.sub(r"\?", "¿", i)) for i in os.listdir(".")]'
}
 grep "ERROR processEvent: /mnt/docs/"  syschecklog.log | sed 's#.*ERROR processEvent: /mnt/docs/ \(/.*\)/.*#\1#' | while read -r DIR
do

    BASEDIR=${DIR%/*}
    if [ "$BASEDIR" != /mnt/cc-docs ]
    then
        ( cd "$BASEDIR" && renameFiles)
    fi

    ( cd "$DIR" && renameFiles)

результаты od -c -txl в файле ошибок;

echo *|od -c -tx1
0000000   O   C   F   -   2   1       I   n   v       2   0   8   3   5
         4f  43  46  2d  32  31  20  49  6e  76  20  32  30  38  33  35
0000020   9   9       A   s   s   e   s   s   M   e   d       $   6   2
         39  39  20  41  73  73  65  73  73  4d  65  64  20  24  36  32
0000040   1   .   5   0       (   H   a   n   g       Q   )       ?
         31  2e  35  30  20  28  48  61  6e  67  20  51  29  20  3f  20
0000060   d   t   d       F   e   b       2   7   _       2   0   1   9
         64  74  64  20  46  65  62  20  32  37  5f  20  32  30  31  39
0000100   1   2   1   7   4   5   8   3  \n
         31  32  31  37  34  35  38  33  0a
0000111

Проверено, что системы используют кодировку eco on hex в ¿, ее присоединение к ней Â, как показано ниже;

$echo -e '\xc2\xbf'
¿

1 Ответ

0 голосов
/ 13 марта 2019

Сценарий снова изменен для дополнительных требований.

(Поскольку я не получил ответы на все вопросы, я изменил сценарий на основе неполной информации.)

Вместо обработки двух каталогов по отдельности сценарий теперь использует find в родительском каталоге (или единственном каталоге), переименовывает и затрагивает все файлы, содержащие '?' во имя. (-name '*\?*').

#! /bin/bash

# Two possible variants because the question was modified.
#
# To process the complete input file as it is now
#  fgrep "ERROR processEvent: /mnt/docs/"  syschecklog.log | ...
#
# To continuously follow the file
# tail -f syschecklog.log| fgrep "ERROR processEvent: /mnt/docs/" | ... 
# The "LANG=C sed ..." avoids problems with invalid UTF-8 characters that do not match '.' in sed's pattern

fgrep "ERROR processEvent: /mnt/docs/"  syschecklog.log | LANG=C sed 's#.*ERROR processEvent: \(/mnt/docs/[^/]*\)/.*#\1#' | while IFS= read -r DIR
do
    find "$DIR" -name '*\?*' | while IFS= read -r FILE
    do
        NEW=$(echo "$FILE"| tr '?' $'\xBF')
        mv "$FILE" "$NEW"
        touch "$NEW"
    done
done

Обратите внимание, что grep и sed переключатся на буферизованный вывод при использовании в конвейере. Это задержит обработку извлеченных строк. Возможно, вам придется отключить буферизацию для команд в конвейере, см. http://mywiki.wooledge.org/BashFAQ/009

2-е значительное обновление

Возникла проблема с недопустимыми символами. В среде UTF-8 sed ведет себя странно, когда ввод содержит байты, которые не являются допустимыми символами UTF-8. Шаблон . не соответствует этим недопустимым символам. (Файл примера содержит байт со значением 0xBF. См. http://www.linuxproblem.org/art_21.html. Установка LANG=C для команды sed устраняет эту проблему.

Я протестировал свой сценарий с добавлением вывода grep к вопросу. Я записал это в файл somelog.log. Я изменил свой сценарий, чтобы использовать grep pattern somelog.log | ... с локальным файлом вместо использования файла журнала с полным путем, которого нет в моей тестовой системе.

После добавления LANG=C к команде sed скрипт успешно запустился с необработанным исходным файлом, предоставленным в качестве внешней ссылки.

Выход

$ grep "ERROR processEvent: /mnt/docs/"  syschecklog.log | sed 's#.*ERROR processEvent: \(/.*\)/.*#\1#' | while read -r DIR; do     BASEDIR=${DIR%/*};     if [ "$BASEDIR" != /mnt/docs/ ];     then         ( cd "$BASEDIR" && renameFiles);     fi;     ( cd "$DIR" && renameFiles); done
bash: cd: /mnt/docs/001234567: No such file or directory
bash: cd: /mnt/docs/001234567/Subdir9876543: No such file or directory
bash: cd: /mnt/docs/002345678: No such file or directory
bash: cd: /mnt/docs/003456789: No such file or directory
bash: cd: /mnt/docs/003456789/Subdir8765432: No such file or directory
... (more similar lines removed)

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

После замены двух команд cd и renameFiles на find ... вывод с моим тестом будет

find: ‘/mnt/docs/001234567’: No such file or directory
find: ‘/mnt/docs/002345678’: No such file or directory
find: ‘/mnt/docs/003456789’: No such file or directory
...
...