Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 在unix中使用带sed的正则表达式筛选文件_Regex_Shell_Unix_Sed - Fatal编程技术网

Regex 在unix中使用带sed的正则表达式筛选文件

Regex 在unix中使用带sed的正则表达式筛选文件,regex,shell,unix,sed,Regex,Shell,Unix,Sed,我正在记录我的工作服务器的一个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/^\(......\)\(....\)\(..\)\(..\)\(

我正在记录我的工作服务器的一个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 `
我不明白这个正则表达式到底是如何过滤掉文件的。了解由该表达式过滤的任何预期输出或示例文件都会很有帮助


有没有办法找到该表达式所接受的可能表达式?

有专门的库(例如Xeger),但为此,我可以向您提供一个示例:

abcdef02122014foobarfoobarfoobar
^     ^ ^ ^   ^
|     | | |   |
1     2 3 4   5
变成

abcdef20140212foobarfoobarfoobar
^     ^   ^ ^ ^
|     |   | | |
1     4   3 2 5
然后我不知道排序做了什么,但是下一个sed只是把上面的一切重新整理好


因此,在恢复原始格式之前,正则表达式似乎用于临时更改排序行的格式。

有专门为此设计的库(例如Xeger),但为此,我可以向您提供一个示例:

abcdef02122014foobarfoobarfoobar
^     ^ ^ ^   ^
|     | | |   |
1     2 3 4   5
变成

abcdef20140212foobarfoobarfoobar
^     ^   ^ ^ ^
|     |   | | |
1     4   3 2 5
然后我不知道排序做了什么,但是下一个sed只是把上面的一切重新整理好


因此,在恢复原始格式之前,正则表达式似乎用于临时更改排序行的格式。

grep-l
在文件列表(
dat*.p
)中搜索正则表达式(
$name
,在您的情况下,或者更好:无论
$name
计算结果如何)然后只打印找到它的文件名

然后,这些文件名通过
sed
命令传递,该命令替换(
s
替换)一些东西,即
^\(……\)\(…\)\(…\)\(…\)\(…\)\(.*)
\1\4\3\2\5
替换(因此它只是重新组合了部分文件名)。然后将转换后的文件名传递到
sort
,然后再次传递到
sed
,这似乎只是撤销了文件名的重新组合

最后,只取最后一个文件名(
tail-1
),其余的都扔掉。这比排序所有文件名要便宜得多,但谁在乎呢;-)


实际上,此行查找与
$name
中的regexp匹配的“最后”文件的名称。“last”的含义由重新分组后的文件名排序决定;假设根据组的大小,我认为时间戳被修改了,因此它从
DDMMYYYY
更改为
YYYYMMDD
,这在某种程度上是有意义的。

grep-l
在文件列表(
dat*.p
)中搜索正则表达式(
$name
在您的情况下,或者更好:无论
$name
的计算结果是什么)然后只打印找到它的文件名

echo "1111112233444456789" | sed -e "s/^\(......\)\(..\)\(..\)\(....\)\(.*\)/\1\4\3\2\5/g"

-> 1111114444332256789
然后,这些文件名通过
sed
命令传递,该命令替换(
s
替换)某些内容,即
^\(…\)\(…\)\(…\)\(…\)\(…\)\(*)
\1\4\3\2\5
替换(因此它只是重新组合了部分文件名)。然后将转换后的文件名传递到
sort
,然后再次传递到
sed
,这似乎只是撤销了文件名的重新组合

最后,只取最后一个文件名(
tail-1
),其余的都扔掉。这比排序所有文件名要便宜得多,但谁在乎呢;-)

实际上,此行查找与
$name
中的regexp匹配的“最后”文件的名称。“last”的含义由重新分组后的文件名排序决定;假设从组的大小来看,我认为时间戳被修改了,因此它从
DDMMYYYY
更改为
YYYYMMDD
,这在某种程度上是有意义的

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
    也不需要(只有一个dur可以替换为
    ^
    表示字符串的开头)
说明:

Begin   111111    22    33    4444    56789
^     \(......\)\(..\)\(..\)\(....\)\(.*\)
        \1        \2    \3    \4      \5
优化:

  • 不需要最后一个
    \(.*)
    ,因此必须删除相应的
    \5
  • 最后一个
    g
    也不需要(只有一个dur可以替换为
    ^
    表示字符串的开头)

关于时间戳的理解很好。@如果我怀疑什么是“s/^(…)(…)(…)(…)(…)(…)(*)/\1\4\3\2\5/g”,那么您应该大致阅读正则表达式。这是一个匹配6+2+2+4+x字符的regexp,将它们分组为6、2、2、4和x字符。这些组在替换中由
\1
\2
等引用。
sed
命令本身就是简单的
s/a/b/c
,它是(正如我所写的)替代(replace)。它将
a
替换为
b
(使用标志
c
,在本例中为
g
,它是“全局”的,在这里没有影响)。关于时间戳的理解很好。@Alfe我怀疑的是确切的是“s/^(…)(…)(…)(…)(.*/\1\4\3\2\5/g”,那么您应该大致阅读正则表达式。这是一个匹配6+2+2+4+x字符的regexp,将它们分组为6、2、2、4和x字符。这些组在替换中由
\1
\2
等引用。
sed
命令本身就是简单的
s/a/b/c
,它是(正如我所写的)替代(replace)。它将
a
替换为
b
(使用标志
c
,在本例中为“全局”且在此没有影响的
g
)。