Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vue.js/6.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
Arrays 如果字符串是由sed命令插入的,awk将在字符串匹配时产生假阳性_Arrays_Bash_Awk_Sed - Fatal编程技术网

Arrays 如果字符串是由sed命令插入的,awk将在字符串匹配时产生假阳性

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

我有一个输入文件、一个参考文件和一个脚本。脚本读取引用文件中的参数;然后,它扫描输入文件中的相同参数,如果值不同,则替换它们的值

每当脚本替换输入文件中的值时,它都会用时间戳记录上一个值,然后将新值写在其下方的换行符中。这为我提供了参数有意义更新的历史记录

输入文件(test.txt)

参考文件(ref.txt)

脚本(script.sh)-感谢Ed Morton提供的格式设置

#!/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