Sed 变量太长
Sed variable too long
我需要用包含数千个路径的 bash 变量替换 json 文件中的 unique 字符串:{FILES}:${文件}
sed -i "s|{FILES}|$FILES|" ./myFile.json
实现该目标的最优雅方法是什么? ${FILES} 的内容是 "aws s3" 命令的结果。内容看起来像:
FILES="/file1.ipk, /file2.ipk, /subfolder1/file3.ipk, /subfolder2/file4.ipk, ..."
我想不出 xargs 可以帮助我的解决方案。
也许 perl 的限制会更少?
perl -pi -e "s#{FILES}#${FILES}#" ./myFile.json
有点恶心,但你可以在shell...
内完成
while read l
do
if ! echo "$l" | grep -q '{DATA}'
then
echo "$l"
else
echo "$l" | sed 's/{DATA}.*$//'
echo "$FILES"
echo "$l" | sed 's/^.*{DATA}//'
fi
done <./myfile.json >newfile.json
#mv newfile.json myfile.json
显然,在您确信它有效之前,我会对最后一行进行评论...
也许只是不这样做?你能不能:
echo "var f = " > myFile2.json
echo $FILES >> myFile2.json
并从您的其他 json 文件中引用 myFile2.json? (如果适合您,您应该将全局 f 变量放入命名空间。)
不要将所有这些变量都放在一个环境变量中,而是将它们放在一个文件中。然后在 perl 中读取该文件:
foo.pl:
open X, "$ARGV[0]" or die "couldn't open";
shift;
$foo = <X>;
while (<>) {
s/world/$foo/;
print;
}
命令 运行:
aws s3 ... >/tmp/myfile.$$
perl foo.pl /tmp/myfile.$$ <myFile.json >newFile.json
希望通过将所有处理拉到 perl 本身来绕过环境变量 space 和参数长度的限制。
最稳妥的方法大概就是让Bash自己展开这个变量。您可以创建一个 Bash 脚本,其中包含 here document 和 myFile.json
的全部内容,占位符 {FILES}
替换为对变量 $FILES
的引用(不是内容本身)。执行此脚本将生成您寻求的输出。
例如,如果 myFile.json
将包含:
{foo: 1, bar: "{FILES}"}
那么脚本应该是:
#!/bin/bash
cat << EOF
{foo: 1, bar: "$FILES"}
EOF
您可以使用单个 sed 命令生成脚本:
sed -e '1i#!/bin/bash\ncat << EOF' -e 's/$/\$/g;s/{FILES}/$FILES/' -e '$aEOF' myFile.json
注意 sed 正在进行两次替换;第一个 (s/$/\$/g
) 转义可能出现在 JSON 数据中的任何美元符号(将每个 $
替换为 $
)。第二个将 {FILES}
替换为 $FILES
;文字 $FILES
, 不是 变量的内容。
现在我们可以将所有内容组合成一个单一的 Bash 单行代码,生成脚本并通过管道将其立即执行到 Bash:
sed -e '1i#!/bin/bash\ncat << EOF' -e 's/$/\$/g;s/{FILES}/$FILES/' -e '$aEOF' myFile.json | /bin/bash
或者更好的是,在不生成子 shell 的情况下执行脚本(如果设置 $FILES
without export 则很有用):
sed -e '1i#!/bin/bash\ncat << EOF' -e 's/$/\$/g;s/{FILES}/$FILES/' -e '$aEOF' myFile.json | source /dev/stdin
输出:
{foo: 1, bar: "/file1.ipk, /file2.ipk, /subfolder1/file3.ipk, /subfolder2/file4.ipk, ..."}
我需要用包含数千个路径的 bash 变量替换 json 文件中的 unique 字符串:{FILES}:${文件}
sed -i "s|{FILES}|$FILES|" ./myFile.json
实现该目标的最优雅方法是什么? ${FILES} 的内容是 "aws s3" 命令的结果。内容看起来像:
FILES="/file1.ipk, /file2.ipk, /subfolder1/file3.ipk, /subfolder2/file4.ipk, ..."
我想不出 xargs 可以帮助我的解决方案。
也许 perl 的限制会更少?
perl -pi -e "s#{FILES}#${FILES}#" ./myFile.json
有点恶心,但你可以在shell...
内完成while read l
do
if ! echo "$l" | grep -q '{DATA}'
then
echo "$l"
else
echo "$l" | sed 's/{DATA}.*$//'
echo "$FILES"
echo "$l" | sed 's/^.*{DATA}//'
fi
done <./myfile.json >newfile.json
#mv newfile.json myfile.json
显然,在您确信它有效之前,我会对最后一行进行评论...
也许只是不这样做?你能不能:
echo "var f = " > myFile2.json
echo $FILES >> myFile2.json
并从您的其他 json 文件中引用 myFile2.json? (如果适合您,您应该将全局 f 变量放入命名空间。)
不要将所有这些变量都放在一个环境变量中,而是将它们放在一个文件中。然后在 perl 中读取该文件:
foo.pl:
open X, "$ARGV[0]" or die "couldn't open";
shift;
$foo = <X>;
while (<>) {
s/world/$foo/;
print;
}
命令 运行:
aws s3 ... >/tmp/myfile.$$
perl foo.pl /tmp/myfile.$$ <myFile.json >newFile.json
希望通过将所有处理拉到 perl 本身来绕过环境变量 space 和参数长度的限制。
最稳妥的方法大概就是让Bash自己展开这个变量。您可以创建一个 Bash 脚本,其中包含 here document 和 myFile.json
的全部内容,占位符 {FILES}
替换为对变量 $FILES
的引用(不是内容本身)。执行此脚本将生成您寻求的输出。
例如,如果 myFile.json
将包含:
{foo: 1, bar: "{FILES}"}
那么脚本应该是:
#!/bin/bash
cat << EOF
{foo: 1, bar: "$FILES"}
EOF
您可以使用单个 sed 命令生成脚本:
sed -e '1i#!/bin/bash\ncat << EOF' -e 's/$/\$/g;s/{FILES}/$FILES/' -e '$aEOF' myFile.json
注意 sed 正在进行两次替换;第一个 (s/$/\$/g
) 转义可能出现在 JSON 数据中的任何美元符号(将每个 $
替换为 $
)。第二个将 {FILES}
替换为 $FILES
;文字 $FILES
, 不是 变量的内容。
现在我们可以将所有内容组合成一个单一的 Bash 单行代码,生成脚本并通过管道将其立即执行到 Bash:
sed -e '1i#!/bin/bash\ncat << EOF' -e 's/$/\$/g;s/{FILES}/$FILES/' -e '$aEOF' myFile.json | /bin/bash
或者更好的是,在不生成子 shell 的情况下执行脚本(如果设置 $FILES
without export 则很有用):
sed -e '1i#!/bin/bash\ncat << EOF' -e 's/$/\$/g;s/{FILES}/$FILES/' -e '$aEOF' myFile.json | source /dev/stdin
输出:
{foo: 1, bar: "/file1.ipk, /file2.ipk, /subfolder1/file3.ipk, /subfolder2/file4.ipk, ..."}