我正在记录我的作业服务器的Shell脚本,它采用一系列以“dat”开头的文件,并对所有这些文件执行特定任务。问题是该脚本使用带有sed命令的正则表达式过滤文件,如下所示:
namecmp=`grep -l $name dat*.p |sed -e "s/^\(......\)\(..\)\(..\)\(....\)\(.*\)/\1\4\3\2\5/g"| sort -t '.' -k 1.7,1.14 |sed -e "s/^\(......\)\(....\)\(..\)\(..\)\(.*\)/\1\4\3\2\5/g" | tail -1 `
我不明白这个正则表达式是如何过滤掉文件的。知道由该表达式过滤的任何预期输出或示例文件将是有帮助的。
有没有办法找到该表达式接受的可能表达式?
答案 0 :(得分:3)
grep -l
在文件列表(dat*.p
)中搜索正则表达式($name
,或者更好:$name
评估为什么)然后打印只有找到它的文件名。
这些文件名然后通过sed
命令传递,该命令替换s
代替某些东西,即^\(......\)\(..\)\(..\)\(....\)\(.*\)
\1\4\3\2\5
(所以它只重新组合部分文件名)。然后,转换后的文件名将传递给sort
,然后再传递给sed
,这似乎取消了重新组合文件名。
最后,只取最后一个文件名(tail -1
),其余所有文件都被丢弃。这比通过对所有文件名进行排序要便宜得多,但是谁在乎; - )
实际上,此行找到与$name
中的正则表达式匹配的“last”文件的名称。 “last”的含义取决于重新组合后文件名的排序;假设从组的大小,我认为时间戳被修改,以便它从DDMMYYYY
更改为YYYYMMDD
,这在某种程度上是有意义的。
答案 1 :(得分:1)
有设计用于实现这一目标的库(例如 Xeger),但为此我可以为您提供一个示例:
abcdef02122014foobarfoobarfoobar
^ ^ ^ ^ ^
| | | | |
1 2 3 4 5
变为
abcdef20140212foobarfoobarfoobar
^ ^ ^ ^ ^
| | | | |
1 4 3 2 5
然后我不知道sort
做了什么,但下一个sed
只是将上述所有内容都按顺序排列。
因此,在恢复原始格式之前,似乎正则表达式用于临时更改行的格式以进行排序。
答案 2 :(得分:0)
echo "1111112233444456789" | sed -e "s/^\(......\)\(..\)\(..\)\(....\)\(.*\)/\1\4\3\2\5/g"
-> 1111114444332256789
解释
Begin 111111 22 33 4444 56789
^ \(......\)\(..\)\(..\)\(....\)\(.*\)
\1 \2 \3 \4 \5
优化:
\(.*\)
,因此必须删除相应的\5
g
(^
只有一次替换,意味着字符串的开头)