如何将文件中的文本提取到变量中,同时用标记替换该文本?
How do I extract text from a file to a variable while also replacing that text with a marker?
我有一个 property: value;
对的文件(它是 CSS)。我想通过这个文件和正则表达式将某些值提取到 shell 变量,同时用标记替换文件中的文本。
例如,对于 FILE1:
position: float;
background: url("data:image/loremipsum");
height: auto;
background: url("data:image/loremipsum2");
假设我想提取图像 url 并将其保存到一个数组中:
FILE1=path/to/file1
URL[0]=$(echo "$FILE1" | grep "data:image" | awk ???)
# Expected: "data:image/loremipsum"
URL[1]=$(echo "$FILE1" | grep "data:image" | awk ???)
# Expected: "data:image/loremipsum2"
然后,从我提取文本的位置,该文本被替换为 "MARKER0"、"MARKER1",依此类推。
我假设这个解决方案涉及 awk,但我输入了 man awk
,我的头差点掉下来。假设我知道如何为此编写正则表达式,我从哪里开始?
我需要awk吗?我需要一个循环来遍历每个图像值吗?
能否请您尝试以下。
arr=($(awk '/background/ && match([=10=],/\".*\"/){print substr([=10=],RSTART+1,RLENGTH-2)}' Input_file))
OR to use a variable's value for awk as an input then try following.
arr=($(echo "$VAR" | awk '/background/ && match([=10=],/\".*\"/){print substr([=10=],RSTART+1,RLENGTH-2)}'))
要打印数组的值,请尝试执行以下操作。
for i in "${arr[@]}"
do
echo "$i"
done
或者要打印正确的元素索引值并打印数组的值,请尝试以下操作。
count=0
for i in "${arr[@]}"
do
echo "arr["$count"]=$i"
count=$((count + 1))
done
编辑: 因为 OP 说值之间可能有 space。因此,可能的解决方案是从 awk
命令打印值,并在值之间添加一个新字符(这将用作 BASH 数组迭代的字段分隔符),我已经采用 %
所以当您 运行 awk 命令时,它会给出以下内容。(使用此处显示的输出中的测试值)
awk '/background/ && match([=13=],/\".*\"/){val=val?val "%" substr([=13=],RSTART+1,RLENGTH-2):substr([=13=],RSTART+1,RLENGTH-2)} END{print val}' Input_file
singh:test/ bla_bla_bla%singh:bla1/bla2
运行 以下命令创建名为 arr
.
的数组
arr=($(awk '/background/ && match([=14=],/\".*\"/){val=val?val "%" substr([=14=],RSTART+1,RLENGTH-2):substr([=14=],RSTART+1,RLENGTH-2)} END{print val}' Input_file))
现在如果我们按照命令设置 IFS='%'
和 运行。
echo "${arr[0]}"
singh:test/ bla_bla_bla
echo "${arr[1]}"
singh:bla1/bla2
因为它采用新的分隔符作为 %
,所以它不会破坏其中包含 space 的值。
我想我会使用更简单的工具。在这种情况下,grep -o
和 bash 数组。 (您没有指定您使用的 shell,所以我假设它是 bash。)
images=($(egrep -o 'data:image/[^"]+' input.css))
或者如果您愿意:
images=($(egrep -o 'url\("data:image/[^"]+"' input.css))
images=(${images[@]#url(\"}); images=(${images[@]%\"})
这两个都创建了一个数组,images[]
,您可以通过多种方式查看它:
$ declare -p images
declare -a images='([0]="data:image/loremipsum" [1]="data:image/loremipsum2")'
$ printf '%s\n' "${images[@]}"
data:image/loremipsum
data:image/loremipsum2
现在.. data:images/值不应包含空格。如果他们这样做了,这个解决方案就会有问题,因为默认情况下数组内容在空白处分割。如果你真的认为你需要保留空格,你可以通过循环读取你的输入来做到这一点:
$ cat input.css
position: float;
background: url("data:image/loremipsum");
height: auto;
background: url("data:image/loremipsum 2");
$ images=(); while read -r; do images+=("$REPLY"); done < <(egrep -o 'data:image/[^"]+' input.css)
$ declare -p images
declare -a images='([0]="data:image/loremipsum" [1]="data:image/loremipsum 2")'
如果您的值包含换行符...那么您只能靠自己了。 :-)
我有一个 property: value;
对的文件(它是 CSS)。我想通过这个文件和正则表达式将某些值提取到 shell 变量,同时用标记替换文件中的文本。
例如,对于 FILE1:
position: float;
background: url("data:image/loremipsum");
height: auto;
background: url("data:image/loremipsum2");
假设我想提取图像 url 并将其保存到一个数组中:
FILE1=path/to/file1
URL[0]=$(echo "$FILE1" | grep "data:image" | awk ???)
# Expected: "data:image/loremipsum"
URL[1]=$(echo "$FILE1" | grep "data:image" | awk ???)
# Expected: "data:image/loremipsum2"
然后,从我提取文本的位置,该文本被替换为 "MARKER0"、"MARKER1",依此类推。
我假设这个解决方案涉及 awk,但我输入了 man awk
,我的头差点掉下来。假设我知道如何为此编写正则表达式,我从哪里开始?
我需要awk吗?我需要一个循环来遍历每个图像值吗?
能否请您尝试以下。
arr=($(awk '/background/ && match([=10=],/\".*\"/){print substr([=10=],RSTART+1,RLENGTH-2)}' Input_file))
OR to use a variable's value for awk as an input then try following.
arr=($(echo "$VAR" | awk '/background/ && match([=10=],/\".*\"/){print substr([=10=],RSTART+1,RLENGTH-2)}'))
要打印数组的值,请尝试执行以下操作。
for i in "${arr[@]}"
do
echo "$i"
done
或者要打印正确的元素索引值并打印数组的值,请尝试以下操作。
count=0
for i in "${arr[@]}"
do
echo "arr["$count"]=$i"
count=$((count + 1))
done
编辑: 因为 OP 说值之间可能有 space。因此,可能的解决方案是从 awk
命令打印值,并在值之间添加一个新字符(这将用作 BASH 数组迭代的字段分隔符),我已经采用 %
所以当您 运行 awk 命令时,它会给出以下内容。(使用此处显示的输出中的测试值)
awk '/background/ && match([=13=],/\".*\"/){val=val?val "%" substr([=13=],RSTART+1,RLENGTH-2):substr([=13=],RSTART+1,RLENGTH-2)} END{print val}' Input_file
singh:test/ bla_bla_bla%singh:bla1/bla2
运行 以下命令创建名为 arr
.
arr=($(awk '/background/ && match([=14=],/\".*\"/){val=val?val "%" substr([=14=],RSTART+1,RLENGTH-2):substr([=14=],RSTART+1,RLENGTH-2)} END{print val}' Input_file))
现在如果我们按照命令设置 IFS='%'
和 运行。
echo "${arr[0]}"
singh:test/ bla_bla_bla
echo "${arr[1]}"
singh:bla1/bla2
因为它采用新的分隔符作为 %
,所以它不会破坏其中包含 space 的值。
我想我会使用更简单的工具。在这种情况下,grep -o
和 bash 数组。 (您没有指定您使用的 shell,所以我假设它是 bash。)
images=($(egrep -o 'data:image/[^"]+' input.css))
或者如果您愿意:
images=($(egrep -o 'url\("data:image/[^"]+"' input.css))
images=(${images[@]#url(\"}); images=(${images[@]%\"})
这两个都创建了一个数组,images[]
,您可以通过多种方式查看它:
$ declare -p images
declare -a images='([0]="data:image/loremipsum" [1]="data:image/loremipsum2")'
$ printf '%s\n' "${images[@]}"
data:image/loremipsum
data:image/loremipsum2
现在.. data:images/值不应包含空格。如果他们这样做了,这个解决方案就会有问题,因为默认情况下数组内容在空白处分割。如果你真的认为你需要保留空格,你可以通过循环读取你的输入来做到这一点:
$ cat input.css
position: float;
background: url("data:image/loremipsum");
height: auto;
background: url("data:image/loremipsum 2");
$ images=(); while read -r; do images+=("$REPLY"); done < <(egrep -o 'data:image/[^"]+' input.css)
$ declare -p images
declare -a images='([0]="data:image/loremipsum" [1]="data:image/loremipsum 2")'
如果您的值包含换行符...那么您只能靠自己了。 :-)