简体   繁体   English

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

[英]shell script to change directory to the tail result path

I'm using Tail to an error happen on the log lines like: 我正在使用尾巴在日志行上发生错误,例如:

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

and this gives results like: 结果如下:

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

So what I do manually is to change the path using cd : 因此,我手动执行的操作是使用cd更改路径:

cd /mnt/docs/003217899/

Is there any script to change directory automatically? 是否有任何脚本可以自动更改目录? As I run another manual script to change file names for the files contained in /003217899/ , those like /003217899/ are happening many times a day, and they are changing, so I need this script to automatically catch those errors, and change the path then run a file name change script. 当我运行另一个手动脚本来更改/003217899/包含的文件的文件名时,像/003217899/这样的文件每天要发生多次,并且它们都在变化,因此我需要此脚本来自动捕获这些错误并更改路径,然后运行文件名更改脚本。

In addition to the above, the log line has another subfolder that contains a error file name like /mnt/docs/003217899/attch/fees ¿ to be paid . 除上述内容外,日志行还有另一个子文件夹,其中包含一个错误文件名,如/mnt/docs/003217899/attch/fees ¿ to be paid How can we cd to that directory? 我们如何cd到该目录?

After Altering [Update] 更改后[更新]

 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

Results: 结果:

[results][1] [结果] [1]

3rd script updated for renameFiles(); 更新了第三个脚本的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

3rd results [3rd results][2] 第三名[第三名] [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 results as you requested; 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) 

Results of 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=

Results of fgrep python yourscript | fgrep python yourscript的结果| od -c -tx1 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

I need to change each '?' 我需要更改每个“?” in the filename to '¿' as the system creates '?' 系统创建“?”时文件名中的“¿” and it shows as '¿', so have to change to that where the server can understand it! 并且显示为“¿”,因此必须更改为服务器可以理解的位置!

I found that Capital A with hat is created by itself in the system, using CAT 我发现使用CAT在系统中自行创建了带帽子的大写字母A

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)

results of od -c -txl, on the error file; 错误文件上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

Checked the systems when using eco on hex encoding on ¿, its attaching  to it as below; 在¿上使用eco on十六进制编码时,检查了系统,其附加Â如下:

$echo -e '\xc2\xbf'
¿

Script modified again for additional requirements. 脚本再次修改以符合其他要求。

(As I did not get answers to all questions I modified the script based on the incomplete information.) (由于我没有得到所有问题的答案,因此我根据不完整的信息修改了脚本。)

Instead of processing two directories separately the script now uses find in the parent directory (or the only directory), renames and touches all files that contain a '?' 该脚本现在不再使用两个目录,而是使用父目录(或唯一目录)中的find ,而不是分别处理两个目录,而是重命名并触摸所有包含“?”的文件。 in the name. 在名字里。 ( -name '*\\?*' ). -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

Note that grep and sed will switch to buffered output when used in a pipeline. 请注意,在管道中使用grepsed它将切换到缓冲输出。 This will delay the processing of the extracted lines. 这将延迟提取行的处理。 You might have to disable buffering for the commands in the pipeline, see http://mywiki.wooledge.org/BashFAQ/009 您可能必须为管道中的命令禁用缓冲,请参阅http://mywiki.wooledge.org/BashFAQ/009

2nd major update 第二次重大更新

There was a problem with invalid characters. 无效字符存在问题。 In a UTF-8 environment sed behaves strangely when the input contains bytes that are not valid UTF-8 charactes. 在UTF-8环境中,当输入包含无效UTF-8特征的字节时, sed行为会很奇怪。 The pattern . 图案. does not match these invalid characters. 与这些无效字符不匹配。 (The example file contains a byte with the value 0xBF . See http://www.linuxproblem.org/art_21.html . Setting LANG=C for the sed command fixes this problem. (示例文件包含一个值为0xBF的字节。请参见http://www.linuxproblem.org/art_21.html 。为sed命令设置LANG=C可以解决此问题。

I tested my script with the grep output added to the question. 我用添加到问题的grep输出测试了我的脚本。 I wrote this into a file somelog.log . 我将此写入文件somelog.log I modified my script to use grep pattern somelog.log | ... 我修改了脚本以使用grep pattern somelog.log | ... grep pattern somelog.log | ... with a local file instead of using a log file with a full path which does not exist on my test system. grep pattern somelog.log | ...使用本地文件,而不是使用具有我的测试系统上不存在的完整路径的日志文件。

After adding LANG=C to the sed command the script ran successfully with the raw input file provided as an external link. sed命令中添加LANG=C后,脚本成功运行,原始输入文件作为外部链接提供。

The output is 输出是

$ 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)

You can see that it tried to cd into the directories from the log messages. 您可以看到它试图从日志消息中cd进入目录。 It does not show parts of the file name. 它不显示文件名的一部分。 In my case it simply failed because the directories don't exist. 就我而言,它只是失败了,因为目录不存在。 I think the script should work. 我认为该脚本应该有效。

After replacing the two cd and renameFiles commands with find ... the output with my test is 更换两个后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
...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM