v
我有一个要从文件中删除的值数组f
。f
是 NUL 分隔的。我该如何进行?我尝试使用sd
,但没有用。
例子:
我有这个文件:
# cat -v $attic
^@this is 1.
this is 2.
this is 3.
^@hi
^@blue boy
而这个变量$i
:
# cat -v <<<"$i"
this is 1.
this is 2.
this is 3.
$i
我想要一个从该文件中删除的命令,结果是:
^@hi
^@blue boy
我试过FROM="$i" perl -pi -e 's/\0\Q$ENV{FROM}\E//g' "$attic"
了,但是如果$i
是多行的话就不行了。我试过FROM="$i" perl -pi0 -e 's/\0\Q$ENV{FROM}\E//g' "$attic"
了,但这没有做任何事情。
既然你提到了
zsh
,你可以这样做:$mapfile
模块中zsh/mapfile
是一个特殊的关联数组,将文件名映射到它们的内容。"${(0@)var}"
:$var
在 NUL 上拆分(并且使用@
内引号保留空元素,如"$@"
)。${array:#pattern}
. 删除与模式匹配的元素。这里的内容$i
是按字面意思理解的,您需要$~i
将其视为一种模式(或启用该globsubst
选项)。${(j:string:)array}
: 将数组的元素与 . 连接起来string
。随着p
,\0
被转换为 NUL。(注意0
上面的参数扩展标志也可以写ps:\0:
)。你可以得到类似的东西
perl
:不同之处在于,
perl
如果还没有 NUL,那么最后会添加一个 NUL(以及常见的问题-i
(断开链接,不保留所有元数据......))。更接近的等价物是:
您的
不起作用,因为:
-pi0
:0
作为参数-i
(备份文件名后缀)-0pi
,那也不能像perl
处理 NUL终止的记录那样起作用,所以记录 ($_
) 将在末尾有 NUL,而不是开始。用于将输入处理-0777
为perl
包含整个输入的一条记录。根据您的输入数据,并假设您的文件足够小以适合内存,这可能对您有用:
将整个文件吞入内存的
-0777
原因。perl
这$ENV{var}
是 perl 访问导出的环境变量的方式。因此$ENV{i}
将获得导出变量的值i
。将s/old/new/g
替换old
为new
全局。\Q
并\E
确保该模式不被解释为正则表达式。最后,由于在分配命令替换的输出(例如)\n?
时,shell 会从变量末尾吃掉换行符,因此需要它,因此实际上可能不包括最后的换行符。var=$(printf 'foo\n')
$i
请注意,这也将匹配子字符串。因此,如果
i
是foo
并且您的文件包含foolish
,那么foo
将被删除离开ish
。如果你不想这样,你可以使用:测试您的示例(替换为 之后
^@
)\0
:当然,这假设
$i
没有尾随换行符。我不知道它是否有,因为cat <<<"$i"
即使没有,也会添加一个。如果您需要对 shell 数组执行此操作,您可以执行以下操作:
重要提示:请注意
-i
上面示例中的内容。这会在适当的位置编辑文件,因此在测试之前将其备份。