Arrays 如果字符串是由sed命令插入的,awk将在字符串匹配时产生假阳性
我有一个输入文件、一个参考文件和一个脚本。脚本读取引用文件中的参数;然后,它扫描输入文件中的相同参数,如果值不同,则替换它们的值 每当脚本替换输入文件中的值时,它都会用时间戳记录上一个值,然后将新值写在其下方的换行符中。这为我提供了参数有意义更新的历史记录 输入文件(test.txt) 参考文件(ref.txt) 脚本(script.sh)-感谢Ed Morton提供的格式设置Arrays 如果字符串是由sed命令插入的,awk将在字符串匹配时产生假阳性,arrays,bash,awk,sed,Arrays,Bash,Awk,Sed,我有一个输入文件、一个参考文件和一个脚本。脚本读取引用文件中的参数;然后,它扫描输入文件中的相同参数,如果值不同,则替换它们的值 每当脚本替换输入文件中的值时,它都会用时间戳记录上一个值,然后将新值写在其下方的换行符中。这为我提供了参数有意义更新的历史记录 输入文件(test.txt) 参考文件(ref.txt) 脚本(script.sh)-感谢Ed Morton提供的格式设置 #!/bin/bash Timestamp=$(date '+%Y%m%d_%H:%M:%S') myhome=/d
#!/bin/bash
Timestamp=$(date '+%Y%m%d_%H:%M:%S')
myhome=/data/stack/testing
awk -F= -v stamp="$Timestamp" '
(NR == FNR && /=/ && !/^#/) {
for (j = 2; j < NF; j++) {
a[$1] = a[$1] $j "="
}
a[$1] = a[$1] $NF
}
(NR != FNR && $1 in a && $1 > 0) {
if ($2 !~ a[$1]) {
$0 = "###EDITED_ON " stamp " from " $2 " to\n" $1 "=" a[$1]
}
}
(NR != FNR && /^#[ a-zA-Z]/) {
b = $1
sub(/# */, "", b)
if (b in a) {
$0 = b "=" a[b]
}
}
(NR != FNR) {
print
}
prep.txt test.txt > tmp && mv tmp test.txt
sed -i 's,$MY_HOME,'"$myhome"',g' test.txt
此if条件意味着,如果替换值已与输入文件中的值相同,则代码将不会写入。这将确保我只看到脚本中有意义的更新。不幸的是,这是返回sed插入的匹配字符串的假阳性的行
问题
awk代码下面有一条sed行,用于替换变量。这使我能够方便地编写ref.txt,其中包含经常出现的值的变量,然后在最后一步中替换它们
出于某种原因,当我用sed替换时,sed的某些内容会改变插入字符串的性质。即使替换值相同,如果我再次运行脚本,awk也会替换它并为新编辑输入时间戳。它正在进行冗余更新。
以下是两次运行脚本后的输出:
testx=1
testy=stack
#testz=3
###EDITED_ON 20200702_11:35:42 from 2 to
foobar=10
###EDITED_ON 20200702_11:35:42 from /data/me/testing to
###EDITED_ON 20200702_11:35:46 from /data/stack/testing to
path=/data/stack/testing
###EDITED_ON 20200702_11:35:42 from /data/me/stack to
plainpath=/data/you/stack
testw=4
请注意,“plainpath”和“foobar”不再编辑。然而,在ref.txt中由变量$MY_HOME定义并由sed替换掉的Path会不断用相同的值更新。我可以无限地运行它,它将始终更新这一行
消除sed线对我的项目来说并不是一个危机,但我感兴趣的是sed和awk为什么会以这种方式交互
问题
- 有人知道为什么sed会改变awk脚本解释文本的方式吗 绳子
- 是否有一种变通方法,可以让我在 保留预期的awk功能,或在 将军
多谢各位 如果脚本认为两个路径值不同
###EDITED_ON 20200702_11:35:46 from /data/stack/testing to
path=/data/stack/testing
。。。然后,您应该假设等号之后的内容(awk脚本中的字段分隔符)确实不同,但实际问题是您看不到差异
如果您看不到,可能是因为行尾的空格字符造成了差异,例如“
”、制表甚至回车(CR),如果您的文件是在Windows上编辑的(在Windows上行尾为CR+LF,但Unix只考虑LF字符)
使用十六进制编辑器或cat-A查看眼睛隐藏的内容。如果脚本认为两个路径值不同
###EDITED_ON 20200702_11:35:46 from /data/stack/testing to
path=/data/stack/testing
。。。然后,您应该假设等号之后的内容(awk脚本中的字段分隔符)确实不同,但实际问题是您看不到差异
如果您看不到,可能是因为行尾的空格字符造成了差异,例如“
”、制表甚至回车(CR),如果您的文件是在Windows上编辑的(在Windows上行尾为CR+LF,但Unix只考虑LF字符)
使用十六进制编辑器或
cat-A
查看眼睛隐藏的内容。没有阅读问题。用hextump检查区别是什么这给了我一个有意义的使用git
的历史记录。或现有的其他版本控制系统。。。只是为了跟踪有意义的更新的历史记录(也就是所谓的版本)。如果sed改变了一些东西,那么您应该比较sed前后的文件,看看有什么不同。请注意,sed的本质是创建一个新文件(新inode)-i标志并不是它所声称的。为了避免这种情况,您可以使用重定向sed。。。test.txt>tmp&&cat tmp>test.txt实际上,我刚刚意识到了原因。这相当愚蠢,但a[$1]=$MY_HOME,所以当比较它们时,它们当然会不一样。sed在awk放置它之后将其扩展为文本,因此在下一次比较中,$2成为文本,[$]1仍然返回$MY_HOME。我现在测试并确认了。我想唯一的误报是我的想法,我遇到了虚假的互动。我应该早点意识到这一点。我应该删除这个问题吗?我没有读这个问题。用hextump检查区别是什么这给了我一个有意义的使用git
的历史记录。或现有的其他版本控制系统。。。只是为了跟踪有意义的更新的历史记录(也就是所谓的版本)。如果sed改变了一些东西,那么您应该比较sed前后的文件,看看有什么不同。请注意,sed的本质是创建一个新文件(新inode)-i标志并不是它所声称的。为了避免这种情况,您可以使用重定向sed。。。test.txt>tmp&&cat tmp>test.txt实际上,我刚刚意识到了原因。这相当愚蠢,但a[$1]=$MY_HOME,所以当比较它们时,它们当然会不一样。sed在awk放置它之后将其扩展为文本,因此在下一次比较中,$2成为文本,[$]1仍然返回$MY_HOME。我现在测试并确认了。我想唯一的误报是我的想法,我遇到了虚假的互动。我应该早点意识到这一点。我应该删除这个问题吗?
testx=1
testy=stack
#testz=3
###EDITED_ON 20200702_11:35:42 from 2 to
foobar=10
###EDITED_ON 20200702_11:35:42 from /data/me/testing to
###EDITED_ON 20200702_11:35:46 from /data/stack/testing to
path=/data/stack/testing
###EDITED_ON 20200702_11:35:42 from /data/me/stack to
plainpath=/data/you/stack
testw=4
###EDITED_ON 20200702_11:35:46 from /data/stack/testing to
path=/data/stack/testing