Shell脚本将目录更改为尾部结果路径

时间:2019-03-13 15:09:01

标签: linux shell automation

我正在使用Tail来在日志行上发生错误,例如:

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]

第三个脚本已针对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
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十六进制编码时检查了系统,如下所示将Â附加到该代码上;

$echo -e '\xc2\xbf'
¿

1 个答案:

答案 0 :(得分:0)

再次修改了脚本以满足其他要求。

(由于我没有获得所有问题的答案,因此我根据不完整的信息修改了脚本。)

脚本现在不再使用两个目录,而是使用父目录(或唯一目录)中的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

请注意,grepsed在管道中使用时将切换到缓冲输出。这将延迟提取行的处理。您可能必须为管道中的命令禁用缓冲,请参见http://mywiki.wooledge.org/BashFAQ/009

第二次重大更新

无效字符存在问题。在UTF-8环境中,当输入包含无效UTF-8特征的字节时,sed的行为会很奇怪。模式.与这些无效字符不匹配。 (示例文件包含一个值为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进入目录。它不显示文件名的一部分。就我而言,它只是失败了,因为目录不存在。我认为该脚本应该可以工作。

将两个cdrenameFiles命令替换为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
...