【问题标题】:Search file A for a list of strings located in file B and append the value associated with that string to the end of the line in file A在文件 A 中搜索位于文件 B 中的字符串列表,并将与该字符串关联的值附加到文件 A 中的行尾
【发布时间】:2015-09-09 23:35:49
【问题描述】:

这有点复杂,我认为是..

我有两个文件,文件 A 和文件 B

文件 A 包含引脚的延迟信息,格式如下

AD22 15484
AB22 9485
AD23 10945

文件 B 包含需要添加此信息的组件声明,格式为:

'DXN_0':
PIN_NUMBER='(AD22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)';
'DXP_0':
PIN_NUMBER='(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,AD23,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)';
'VREFN_0':
PIN_NUMBER='(AB22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)';

所以我想要实现的是以下输出

'DXN_0':
PIN_NUMBER='(AD22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)';
PIN_DELAY='15484';
'DXP_0':
PIN_NUMBER='(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,AD23,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)';
PIN_DELAY='10945';
'VREFN_0':
PIN_NUMBER='(AB22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)';
PIN_DELAY='9485';

文件A或B中的pin编号没有顺序

所以我假设需要发生以下情况

  • 打开文件 A,读取第一行
  • 在文件 B 中搜索刚刚读取的行中的第一个字符串字段
  • 在文件 B 中找到后,在行尾添加文本“\nPIN_DELAY='”
  • 添加从文件A读取的行的第二个字符串字段
  • 在“';”末尾添加以下文本
  • 重复打开文件A,读取第二行

我假设它将是 sed 和 awk 命令的组合,我目前正在尝试解决它,但我认为这超出了我的知识范围。非常感谢,因为我知道这很复杂..

【问题讨论】:

  • 展示你的一些努力会很有趣。 Not very long ago我发布了您的问题的答案,给出了一些全面的解释,这可能是一个很好的起点。

标签: bash file awk sed


【解决方案1】:
FILE2=`cat file2`
FILE1=`cat file1`
TMPFILE=`mktemp XXXXXXXX.tmp`
FLAG=0
for line in $FILE1;do
    echo $line >> $TMPFILE 
    for line2 in $FILE2;do
    if [ $FLAG == 1 ];then
        echo -e "PIN_DELAY='$(echo $line2 | awk -F " " '{print $1}')'" >> $TMPFILE
        FLAG=0
    elif [ "`echo $line | grep $(echo $line2 | awk -F " " '{print $1}')`" != "" ];then
        FLAG=1
    fi
    done
done
mv $TMPFILE file1

对我有用,如果用户发送 sigint,您还可以添加一个删除 tmp 文件的陷阱。

【讨论】:

  • 非常感谢,只是看看我能不能让它发挥作用 - 是的,我想的有点超出我的知识范围哈哈......不知道你怎么这么快就到那里了,太棒了..
  • 嗨@Glastis,非常感谢您回答我的问题。我已经让它工作了,并且可以通过不时打开 XXX.tmp 文件来看到它正在消失。我没有提到的是这些文件的大小(完全是我的错)。文件中有超过 2000 个 pin 条目,虽然我相信它会做到这一点,但它需要时间。这当然不是我最初的问题,所以完全是我的错。我从你的代码中学到了更多关于文件 IO 和“awk”的知识,所以我很感激你花时间这样做:)
  • 嗨,(我在这里发帖是因为我无法对您的回复发表评论),mktemp 允许您创建一个临时文件并回显其名称,但它对于防止新的 tmp 文件擦除非常有用另一个同名的 tmp 文件。如果你想防止这种情况发生,你应该使用 DELAYS.txt.XXXXX 之类的名称,mktemp 将用随机字符替换每个 'x'。
  • 啊,是的,还有一个非常有用的东西,我不知道哈哈 - 我会修改我的脚本!!!这是确保将其视为临时文件并应被忽略的好方法。非常感谢您留下此评论,我每天都在学习一些东西,并开始写一本小日志,其中包含这些有用的东西。非常感谢您的帮助,谢谢@Glastis
【解决方案2】:

求救...

$ awk -vq="'" 'NR==FNR{a[$1]=$2;next} {print; for(k in a) if(match($0,k)) {print "PIN_DELAY=" q a[k] q ";"; next}}' keys data 

'DXN_0':
PIN_NUMBER='(AD22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)';
PIN_DELAY='15484';
'DXP_0':
PIN_NUMBER='(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,AD23,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)';
PIN_DELAY='10945';
'VREFN_0':
PIN_NUMBER='(AB22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)';
PIN_DELAY='9485';

说明:扫描第一个文件中的键/值对。对于第二个数据文件中的每一行,打印该行,对于任何匹配的键,以请求的格式打印键的值。 awk 中的单引号有点棘手,设置 q 变量是处理它的一种方法。

【讨论】:

  • awk 来救援@karakfa,干得好,我刚刚输入了我的代码,它在几秒钟内将其整理出来,闪烁着光芒。很高兴您可以看到它正在处理数据(在这种情况下大约有 2000 个引脚)。我对 Linux 和 awk 了解得越多,我就意识到它是多么强大。不幸的是,我没有花足够的时间使用这些功能,因此下次我需要做某事时,我会忘记我学到了什么,所以我非常感谢你所做的努力,欢呼,非常感谢。
【解决方案3】:

我的应用程序的最终脚本,非常感谢所有帮助..

! /usr/bin/sh

Adam 在 stackoverflow 用户的大量帮助下创建的脚本

必须通过 $1 文件(来自 Xilinx 的包文件)

必须通过$2文件(来自PCB设计办公室的chips.prt文件)

删除这些临时文件,如果不存在则抛出错误,哎呀!!

rm DELAYS.txt CHIP.txt OUTPUT.txt

感谢 Glatis@stackoverflow https://stackoverflow.com/users/5101968/glastis 为代码创建临时文件,我现在知道该怎么做

延迟=mktemp DELAYS.txt 芯片=mktemp CHIP.txt 输出=mktemp OUTPUT.txt

BELOW::grep 输入文件 1(来自 Xilinx 的 pkg 文件)用于包含 n.n 形式的延迟的行,并使用 TAIL 删除某些内容(不记得),sed 删除空格并替换为单个空格,sed要删除 \n 之前的空格,请使用 awk 打印第 3、9、10 列并再次输入 awk 以计算 fedorqui@stackoverflow https://stackoverflow.com/users/1983854/fedorqui 提供的延迟

在awk中,NF指的是当前行的字段数。由于 $n 指的是字段编号 n,因此 $(NF-1) 我们指的是倒数第二个字段。

{...}1 做一些事情,然后打印结果行。 1 评估为 True,任何 True 都会触发 awk 执行其默认操作,即打印当前行。

$(NF-1) + $NF)/2 * 141 执行计算:`(倒数第二个 + 最后一个) / 2 * 141

{$(NF-1)=sprintf( ... ) 将前面计算的结果分配给倒数第二个字段。将 sprintf 与 %.0f 一起使用,我们确保执行舍入,如上所述。

{...; NF--} 一旦计算完成,我们就会在倒数第二个字段中得到它的结果。要删除最后一列,我们只需说“嘿,减少字段数”,以便“删除”最后一列。

grep -E -0 '[0-9].[0-9]' $1 |尾-n +2 | sed -e 's/[[:blank:]]+/ /g' -e 's/\s\n/\n/g' | awk '{print ","$3",",$9,$10}' | awk '{$(NF-1)=sprintf("%.0f", ($(NF-1) + $NF)/2 * 169); NF--}1' >> $DELAYS

删除部分文件中的空格并添加额外的逗号 (,) 以便以下 awk 命令正常工作

猫 $2 | sed -e "s/[[:blank:]]+//" -e "s/(/(,/g" -e 's/)/,)/g' >> $CHIP

此awk 命令由karakfa@stackoverflow https://stackoverflow.com/users/1435869/karakfa 提供说明:扫描第一个文件中的键/值对。对于第二个数据文件中的每一行,打印该行,对于任何匹配的键,以请求的格式打印键的值。 awk 中的单引号有点棘手,设置 q 变量是处理它的一种方法。 Search file A for a list of strings located in file B and append the value associated with that string to the end of the line in file A

awk -vq="'" 'NR==FNR{a[$1]=$2;next} {打印; for(k in a) if(match($0,k)) {print "PIN_DELAY=" q a[k] q ";";下一个}}' $DELAYS $CHIP >> $OUTPUT

删除之前在 before ) 和 after ( 中添加的额外逗号 (,) 就完成了..

猫 $OUTPUT | sed -e 's/(,/(/g' -e 's/,)/)/g' >> 芯片d.prt

【讨论】:

    猜你喜欢
    • 2016-12-03
    • 1970-01-01
    • 2023-02-21
    • 2018-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-11
    相关资源
    最近更新 更多