【问题标题】:grep values and re-arranging the filegrep 值并重新排列文件
【发布时间】:2015-12-19 23:41:06
【问题描述】:

嗨,我有一个文件名 test.txt

    (standard input):8:      <property name="ProcedureName" value="abc"/>
(standard input):7:         <property name="PackageName" value="123abc"/>
(standard input):8:         <property name="ProcedureName" value="bac"/>
(standard input):7:      <property name="PackageName" value="bac123"/>
(standard input):8:      <property name="ProcedureName" value="cde"/>
(standard input):7:      <property name="PackageName" value="cd123"/>
(standard input):8:      <property name="ProcedureName" value="b4u"/>
(standard input):7:      <property name="PackageName" value="b4u234"/>

我必须以以下格式从这个文件中仅 grep 包名和 procdeurename 的值:到一个 o/p 文件中

abc/123abc
bac/bac123
cde/cd123
b4u/b4u234

尝试过 cut 和 awk 但无法得到它

【问题讨论】:

  • 向我们展示你的尝试

标签: shell awk sed grep cut


【解决方案1】:

awk 应该可以为您做到这一点:

awk -F'"' 'BEGIN { OFS="/" } $2=="ProcedureName"{procedureName=$4} $2=="PackageName" { print procedureName,$4 }' yourfilename

这将使用双引号作为分隔符。它测试位置 2 中的字符串“ProcedureName”并将位置 4 存储在变量 procedureName 中。然后,如果它在位置 2 中找到“PackageName”,它会打印出存储的 procedureName 和位置 4 中的内容。它使用反斜杠作为 OutputFieldSeperator。

从技术上讲,您可以通过管道将您的 grep 传递给此,但 awk 可以自己进行搜索,这就是我在这里写的。

【讨论】:

    【解决方案2】:

    试试这个awk:

    awk -F'"' 'NR%2{p1=$4;next} {print p1 "/" $4}' 
    

    测试:

    $ awk -F'"' 'NR%2{p1=$4;next} {print p1 "/" $4}' file
    abc/123abc
    bac/bac123
    cde/cd123
    b4u/b4u234
    

    【讨论】:

    • 这也有效:awk -F\" -v OFS=/ '{printf "%s%s", $4, NR%2?OFS:ORS}' file
    • @EdMorton,谢谢。更新了答案。
    【解决方案3】:

    我的第一次尝试(也是我真正推荐的)与 @sat 的相同,所以我删除了它,这是一种不同的方法,以防它在其他情况下有用:

    $ awk -F'"' '{n2v[$2]=$4} !(NR%2){print n2v["ProcedureName"] "/" n2v["PackageName"] }' file
    abc/123abc
    bac/bac123
    cde/cd123
    b4u/b4u234
    

    n2v 表示name2value,我经常使用的数组名称,用于我们在输入文件中具有名称到值映射的应用程序类型。

    【讨论】:

      【解决方案4】:

      使用 GNU grep 并粘贴:

      grep -oP '"\K[^"]*(?="/)' file | paste -d / - -
      

      输出:

      abc/123abc bac/bac123 cde/cd123 b4u/b4u234

      【讨论】:

      • 我的想法完全一样,虽然我会使用'(?&lt;=value=").*?(?=")'
      • @glennjackman:是的,我昨天找到了你的想法there
      【解决方案5】:

      作为awkgrep 解决方案的替代方案。

      sed -rn 's|.*"([^"]*)"/>|\1|p' xml | pr -2ats/
      

      【讨论】:

        【解决方案6】:

        这可能对你有用(GNU sed):

        sed 'N;s#.*value="\([^"]*\)".*value="\([^"]*\)".*#\1/\2#' file
        

        一次读取两行并提取前面有文字value= 的双引号之间的值。

        另一个稍短的版本在 LHS 中使用反向引用和 -r 选项使正则表达式更易于阅读:

        sed -r 'N;s#.*(value=")([^"]*)".*\1([^"]*)".*#\2/\3#' file
        

        另一种方式,使用保持空间和替换:

        sed -r 's/.*"(.*)".*/\1/;h;N;s//\1/;H;g;s#\n#/#' file
        

        提取两个连续行中双引号之间的最后一个值,并将结果重新排列为所需的字符串。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-08-28
          • 2020-02-18
          • 1970-01-01
          • 2019-06-20
          • 1970-01-01
          • 2012-02-03
          相关资源
          最近更新 更多