Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.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
如何在bash中使用sed/awk将字符串从模式剪切到模式_Awk_Sed - Fatal编程技术网

如何在bash中使用sed/awk将字符串从模式剪切到模式

如何在bash中使用sed/awk将字符串从模式剪切到模式,awk,sed,Awk,Sed,我不知道如何使用sed或awk来修剪文件中的字符串。我已经搜索了好几个小时,没有得到想要的结果。 我有这样一个字符串: c=one, o=roll, root ca valid until: date c=one, o=roll, root ca Located: location c=two roll, root ca valid until: date c=two roll, root ca Located:

我不知道如何使用sed或awk来修剪文件中的字符串。我已经搜索了好几个小时,没有得到想要的结果。 我有这样一个字符串:

c=one, o=roll, root ca          valid until: date
c=one, o=roll, root ca          Located: location
c=two roll, root ca             valid until: date
c=two roll, root ca             Located: location
我所需的输出在列中对齐:

c=one            valid until: date
c=one            Located: location
c=two roll       valid until: date
c=two roll       Located: location
我使用的sed命令与(以及其他许多命令)不同:

但在同一个命令中添加“valid”和“Location”之前,我无法计算出第二个条件。
非常感谢

请您尝试以下内容,并用显示的样本进行测试和书写

awk -F'[, ]' 'match($0,/ +valid.*| +Located.*/){print $1,substr($0,RSTART,RLENGTH)}' Input_file

我将删除所有内容,直到有多个连续的空格,假设左列中没有双空格:

s/,.*     /     /
您可以将术语
有效
位于
(以及您想要的任何其他此类术语)放入一个替代捕获组中。然后使用替换部分中的backreference
\1
将其放回原处

要对齐输出,可以使用输入中不出现的一些字符,如
|
,然后使用
命令

$ sed -E 's/,.*(valid|Located)/|\1/' ip.txt | column -t -s'|'
c=one       valid until: date
c=one       Located: location
c=two roll  valid until: date
c=two roll  Located: location

您不必依赖
valid
Located
,使用下面的命令,其中可以有任何单词:

sed 's/,.*[^ ]\(   *[^ ][^:]*:\)/\1/'  file
或者,您可以使用强制匹配到
有效
定位

sed -E 's/,.*[^[:space:]]([[:space:]]{2,}(valid|Located))/\1/' file
sed -E 's/,.*\S(\s{2,}(valid|Located))/\1/' file     # If \s and \S are supported
其中
(有效|定位)
有效
定位
字符序列匹配。请注意,要使OR
|
操作符工作,您需要在POSIX BRE模式中对其进行转义,或者使用
-E
选项启用POSIX ERE语法,如上所示

请参阅和详细信息

  • -匹配第一个逗号
  • *
    -匹配任何0个或更多字符
  • [^]
    -然后找到一个非空格字符
  • \(*[^][^:]*:\)
    -捕获到组1(
    \1
    )2个或多个空格,后跟一个非空格字符(
    [^]
    ),然后是0个或多个字符,而不是
    [^:*
    ),然后是一个

您可以将空格替换为
\s
(如果支持)或
[:space:]
以匹配任何空格,将
[^]
替换为
[^[:space:]
\s
(如果支持)。

sed
没有类似lookaround和lookaheads的高级正则表达式功能,“直到”只能用贪婪的方式来做。看看你写的。你能看出你的逻辑中有一个微妙的错误吗?也许你在找。是的,这就是我为什么问这里的原因…谢谢,它工作得很好,但这打破了列中的对齐方式,有办法保持它吗?谢谢,有输出:
c=one有效期至:date c=one Located:location c=two roll有效期至:date c=two roll Located:location
@geofry,我相信它也保留了有效或定位之前的空格。遗憾的是,不,它可以通过长脚本中的另一个格式化来完成,但是我犯了一个错误,因为您的命令将所有内容都保留在行的开头,从第一个空格开始,直到逗号出现,但非常感谢effort@GeoFery我很高兴它成功了,但我看到你有些怀疑。你需要调整它来做其他事情吗?不,那很好,只是想保持Sundeep更新的列。谢谢。
sed 's/,.*[^ ]\(   *[^ ][^:]*:\)/\1/'  file
sed -E 's/,.*[^[:space:]]([[:space:]]{2,}(valid|Located))/\1/' file
sed -E 's/,.*\S(\s{2,}(valid|Located))/\1/' file     # If \s and \S are supported