[英]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. 请注意,在管道中使用
grep
和sed
它将切换到缓冲输出。 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 更换两个后
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
...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.