在单行命令中使用grep-awk和sed导致“无此类文件或目录”错误

时间:2017-01-23 10:51:39

标签: awk grep

..我知道原因:

我有一个包含大量信息的xml文档。我需要提取我需要的内容并最终将它们打印在新文件中。

xml(好吧,它的一部分..行只是不断重复)

<module classname="org.openas2.processor.receiver.AS2DirectoryPollingModule"
    outboxdir="%home%/../../../home/samba/user/Outbound/toMartha/"
    errordir="%home%/../../../home/samba/user/Outbound/toMartha/error"
    sentdir="%home%/../../../home/samba/user/data/Sent/Martha"
    interval="600"
    defaults="sender.name=me_myself, receiver.name=Martha"
    sendfilename="true"
    mimetype="application/standard"/>

<module classname="org.openas2.processor.receiver.AS2DirectoryPollingModule"
    outboxdir="%home%/../../../home/samba/user/Outbound/toJosh/"
    errordir="%home%/../../../home/samba/user/Outbound/toJosh/error"
    sentdir="%home%/../../../home/samba/user/data/Sent/Josh"
    interval="600"
    defaults="sender.name=me_myself, receiver.name=Josh"
    sendfilename="true"
    mimetype="application/standard"/>

<module classname="org.openas2.processor.receiver.AS2DirectoryPollingModule"
    outboxdir="%home%/../../../home/samba/user/Outbound/toPamela/"
    errordir="%home%/../../../home/samba/user/Outbound/toPamela/error"
    interval="600"
    defaults="sender.name=me_myself, receiver.name=Pamela"
    sendfilename="true"
    mimetype="application/standard"/>

我需要在“Outbound”之后提取文件夹并用引号或斜杠清除它。 此外,我需要排除“/错误”,因此每个只得到1个结果。

我的命令是:

grep -o -v "/error" "Outbound/" config.xml | awk -F"Outbound/" '{print $2}' | sed -e "s/\/\"//g" > /tmp/sync_users

错误是:grep: Outbound/: No such file or directory这当然意味着我给了grep太多的参数(?) - 如果我删除了-v "/error"它会起作用但是会打印名称“ /错误”。

有人能帮助我吗?

修改 正如一些人在他们的例子中指出的那样(感谢您投入的时间),我需要根据上面的示例提取这些词:

toMartha
toJosh
toPamela

6 个答案:

答案 0 :(得分:3)

在这种情况下,

可能会使用 sed

sed -e '\#/Outbound/#!d' -e '\#/error"$#d' -e 's#.*/Outbound/##;s#/\{0,1\}"$##' Config.xml 

awk 版本,假设(最后一次打印)您的行总是在Outbound下面的1个文件夹中显示

awk -F '/' '$0 !~ /\/Outbound\// || /\/error"$/ {next} {print $(NF-1)}' Config.xml

答案 1 :(得分:2)

完全放松<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>2.0</version> </dependency>

grep
  • $ awk '/outboxdir/{gsub(/^.+Outbound\/|\/" *\r?$/,""); print}' file toMartha toJosh toPamela /^outboxdir/仅处理 /outboxdir/开头的记录
  • outboxdir删除记录中不需要的部分
  • 在记录结束时添加了空间删除,并为Windows源文件添加了CRLF修复

答案 2 :(得分:1)

怎么样:

grep -i "outbound" your_file | awk -F"Outbound/" '{print $2}' | sed -e 's/error//' -e 's/\/\"//' | uniq

应该工作:)

答案 3 :(得分:1)

要给出grep倍数模式,它们必须用换行符分隔或由倍数模式选项(-e,F,..)指定。但是-v将匹配作为一个整体反转,你不能只反转一个。

您可以使用PCRE(-P参数)获得外观能力:

grep -o -P '(?<=Outbound\/)[^\/]+(?!.*\/error)' config.xml

正则表达式演示here

正则表达式尝试

  • 至少匹配一次不是斜线的东西,[^\/]+
  • 前面有Outbound/肯定的后方(?<=Outbound\/)
  • 并且后面没有以/error结尾的内容,否定前瞻(?!.*\/error)

使用您的第一个样本输入:

$ grep -o -P '(?<=Outbound\/)[^\/]+(?!.*\/error)' test.txt
toMartha
toJosh
toPamela

答案 4 :(得分:0)

您可以在match中使用gawk并在正则表达式中捕获群组

awk 'match($0, /^.*\/Outbound\/([^\/]+)\/([^\/]*)\/?"$/, a){
    if(a[2]!="error"){print a[1]}
}' config.xml

你明白了,

toMartha
toJosh
toPamela

答案 5 :(得分:0)

grep可以使用-e选项(又名--regexp)接受多种模式,即使它也可以与--fixed-strings一起使用,请参阅图。但是,-v--invert-match)作为一个组适用于所有模式。

另一个解决方案是将两个调用链接到grep

grep -v "/error" config.xml | grep "Outbound/" | awk -F"Outbound/" '{print $2}' | sed -e "s/\/\"//g"