Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/23.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
Linux 用另一个列表中的下一行替换列表中的字符串_Linux_Awk_Sed_Grep - Fatal编程技术网

Linux 用另一个列表中的下一行替换列表中的字符串

Linux 用另一个列表中的下一行替换列表中的字符串,linux,awk,sed,grep,Linux,Awk,Sed,Grep,我有3个文件。一个是食品和类别列表: food="rice" product="cereal" food="beans" product="bean" food="cake" product="bakery" food="lettuce"

我有3个文件。一个是食品和类别列表:

                 food="rice"
                 product="cereal"
                 food="beans"
                 product="bean"
                 food="cake"
                 product="bakery"
                 food="lettuce"
                 product="leaves"
第二个是仅列出以下食品的清单:

                 food="rice"
                 food="beans"
                 food="cake"
                 food="lettuce"
在第三个文件中,我有几行包含/food file字符串,例如/food=rice,我需要用第一个文件中列出的相应产品替换这些字符串。为了简化:在文件3中找到文件2中的字符串,并替换为文件3中文件1的下一行。 我想可能是grep和sed的组合,但我不知道如何。。。 第三个文件看起来像这样

>[food="rice"] [some other sutff] [calories=398]
Here is a recipe with rice
>[food="beans"] [some other sutff] [calories=250]
Here is a recipe with beans
>[food="cake"] [some other sutff] [calories=100]
Here is a recipe for cake
>[food="lettuce"] [some other sutff] [calories=02]
Why would you need a recipe for lettuce?
我需要它看起来像

 >[product="cereal"] [some other sutff] [calories=398]
 Here is a recipe with rice
 >[product="bean"] [some other sutff] [calories=250]
 Here is a recipe with beans
 >[product="bakery" [some other sutff] [calories=100]
 Here is a recipe for cake
 >[product="leaves"] [some other sutff] [calories=02]
 Why would you need a recipe for lettuce?
这是一个sed/awk组合

$ sed -f <(awk '     {gsub(/ /,"")} 
             NR==FNR {if(/food/) k=$0; if(/product/) a[k]=$0; next} 
             $0 in a {print "s/" $0 "/" a[$0] "/g"}' f1 f2) f3

>[product="cereal"] [some other sutff] [calories=398]
Here is a recipe with rice
>[product="bean"] [some other sutff] [calories=250]
Here is a recipe with beans
>[product="bakery"] [some other sutff] [calories=100]
Here is a recipe for cake
>[product="leaves"] [some other sutff] [calories=02]
Why would you need a recipe for lettuce?
下面是一个使用sed的解决方案:

如果第一个文件的每一行都以空格开头,那么就变成了空白

sed -f <(sed 'N;s/ *//g;s/\n/\//;s/^/s\//;s/$/\//' one ) three

我看不出file2将用于什么

$ cat tst.awk
BEGIN { FS="[][]" }
NR==FNR {
    gsub(/^[[:space:]]+|[[:space:]]+$/,"")
    if (NR%2) { food = $0 }
    else { map[food] = $0 }
    next
}
{
    sub(/\[[^][]+/,"["map[$2])
    print
}

$ awk -f tst.awk file1 file3
>[product="cereal"] [some other sutff] [calories=398]
Here is a recipe with rice
>[product="bean"] [some other sutff] [calories=250]
Here is a recipe with beans
>[product="bakery"] [some other sutff] [calories=100]
Here is a recipe for cake
>[product="leaves"] [some other sutff] [calories=02]
Why would you need a recipe for lettuce?

你能不能把第三个文件的样本和预期的输出样本一起发布,然后让我们知道?我刚刚更新了后请避免给我代码问题。而是显示您正在处理的脚本,并说明问题所在。另见@SilviaJusti,仍然不清楚,请详细说明?为什么您需要第二个文件仅包含食物?几乎,我只希望>[food=rice]更改为>[food=Graines],下一行应该保持完整,并且仍然说rice。。。它需要精确匹配,不仅要匹配类别,还要匹配toofixed字符串的其余部分,只要没有空格就可以了,否则您需要从标记中删除它们。非常感谢您纠正我的错误。我修正了我的答案。
$ cat tst.awk
BEGIN { FS="[][]" }
NR==FNR {
    gsub(/^[[:space:]]+|[[:space:]]+$/,"")
    if (NR%2) { food = $0 }
    else { map[food] = $0 }
    next
}
{
    sub(/\[[^][]+/,"["map[$2])
    print
}

$ awk -f tst.awk file1 file3
>[product="cereal"] [some other sutff] [calories=398]
Here is a recipe with rice
>[product="bean"] [some other sutff] [calories=250]
Here is a recipe with beans
>[product="bakery"] [some other sutff] [calories=100]
Here is a recipe for cake
>[product="leaves"] [some other sutff] [calories=02]
Why would you need a recipe for lettuce?