【问题标题】:string replacement using awk command使用 awk 命令替换字符串
【发布时间】:2015-03-13 20:42:11
【问题描述】:

这是我之前的帖子 string replacement using awk command 的延续,它没有 100% 完全解决。为了更清楚......

(我使用的源文件和代码在文末)

要求 1

如果我没有查找数据(例如,对于“u_no”不在参考文件中,当前解决方案将打印一个空字段。

aaaa
uid=1a1a
pwd=1b1b
u_no=

我希望它改为从源文件中选择值..

aaaa
uid=1a1a
pwd=1b1b
u_no=12345

要求 2

如果源文件或参考文件中的数据混淆了,它仍然应该正确地进行替换。

也就是说,当ref文件这样改变时:

block,parameter,value
aaaa,uid,1a1a
aaaa,pwd,1b1b
bbbb,uid,2a2a
zzzz,pwd,9b9b
zzzz,uid,9a9a
bbbb,pwd,2b2b

为此,我得到了

aaaa
uid=1a1a
pwd=1b1b
u_no=
bbbb
uid=2a2a
pwd=9b9b
zzzz
uid=9a9a
pwd=2b2b

** 我必须得到**

aaaa
uid=1a1a
pwd=1b1b
u_no=12345    #points to my req 1 
bbbb
uid=2a2a
pwd=2b2b
zzzz
uid=9a9a
pwd=9b9b

我希望搜索和替换基于块 aaaa,bbbb,zzzz,etc.. 不按顺序进行。 (例如,这里bbbb 的pwd 值应该是2b2b 而不是9b9b)。

源文件(src.txt)

aaaa
uid=xxxx
pwd=nnnn
u_no=12345
bbbb
uid=yyyy
pwd=eeee
zzzz
uid=yyyy
pwd=eeee

注意bbbb 的uid 和pwd 值与src 文件中zzzz 的值相同。

参考文件(ref.txt)

block,parameter,value
aaaa,uid,1a1a
aaaa,pwd,1b1b
bbbb,uid,2a2a
zzzz,pwd,9b9b
zzzz,uid,9a9a
bbbb,pwd,2b2b

注意:ref 文件中记录的顺序也可能会改变,正如我在需求 2 中提到的那样。bbbb 的 uid 和 pwd 的查找值与 zzzz 的查找值不同。但我需要的结果如下:-

要求的输出文件(src_out.txt)(包括要求1和2)

aaaa
uid=1a1a
pwd=1b1b
u_no=12345
bbbb
uid=2a2a
pwd=2b2b
zzzz
uid=9a9a
pwd=9b9b

代码

$ cat tst.awk
BEGIN { FS = "[,=]+" }
NR==FNR {
    if (NR>1) {
        map[$1,$2] = $3
    }
    next
}
{
    if (NF==1) {
        key = $0
    }
    else {
        $0 = $1 "=" map[key,tolower($1)]
    }
    print
}

$ awk -f tst.awk ref.txt src.txt

这符合我最初的预期,但现在添加了我在此处指定的 requirement 1 和 requirement 2,因此我需要解决这些问题。

【问题讨论】:

标签: unix awk sed


【解决方案1】:

这是awk的一种解决方案

awk -F= '
FNR==NR {
    split($0,b,",")
    a[b[1] FS b[2]]=b[3]
    next} 
!/=/ {
    f=$1
    print
    next} 
    {
    print $1"="(a[f FS $1]?a[f FS $1]:$2)}
' ref.txt src.txt
aaaa
uid=1a1a
pwd=1b1b
u_no=12345
bbbb
uid=2a2a
pwd=2b2b
zzzz
uid=9a9a
pwd=9b9b

【讨论】:

  • 它工作正常...如果我需要将参数发送到 AWK 程序..如何发送到这里? ...这里我想根据某些条件从参考文件中获取第 3 列或第 4 列或第 5 列....所以键将变为... a[b[1] FS b[2]]= b[3].....或.... a[b[1] FS b[2]]=b[4].....或.....a[b[1] FS b [2]]=b[5]...读取参考文件时...如何参数化这个b[...]...???
  • @Sanish 在此处阅读我关于将数据旅馆获取到awk 的答案:stackoverflow.com/questions/19075671/…
  • 先生...帮助很大...谢谢...我使用的是 Sun OS 5.10...它显示代码中该行的语法错误..."! /=/ {" .... 有解决方法吗? .....但它在红帽中工作得很好......
  • 这个!/=/ { 测试该行是否不包含= 并且应该适用于awk 的所有版本。您可以尝试将其替换为$0!~/=/ {
  • @Sanish 在 Solaris 上使用 nawk(新 awk)或 /usr/xpg4/bin/awk(POSIX awk)。
【解决方案2】:

调整以测试 ref 文件中是否存在 src 值:

$ cat tst.awk
BEGIN { FS = "[,=]+" }
NR==FNR {
    if (NR>1) {
        map[$1,$2] = $3
    }
    next
}
{
    if (NF==1) {
        key = $0
    }
    else if ( (key,tolower($1)) in map ) {
        $0 = $1 "=" map[key,tolower($1)]
    }
    print
}

$ awk -f tst.awk ref.txt src.txt
aaaa
uid=1a1a
pwd=1b1b
u_no=12345
bbbb
uid=2a2a
pwd=2b2b
zzzz
uid=9a9a
pwd=9b9b

【讨论】:

  • 会检查并通知您先生...谢谢! :)
猜你喜欢
  • 1970-01-01
  • 2014-10-19
  • 2023-04-11
  • 2017-02-08
  • 2021-05-16
  • 1970-01-01
  • 2011-08-15
  • 2015-01-13
  • 1970-01-01
相关资源
最近更新 更多