如何将文件中的文本提取到变量中,同时还用标记替换该文本?

时间:2019-02-15 00:30:44

标签: bash shell awk text-processing

我有property: value;对文件(它是CSS)。我想浏览该文件,然后用正则表达式将某些值提取到shell变量中,同时用标记替换文件中的文本。

例如FILE1:

position: float;
background: url("data:image/loremipsum");
height: auto;
background: url("data:image/loremipsum2");

假设我要提取图像网址并将其保存到数组中:

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吗?我是否需要循环遍历每个图像值?

2 个答案:

答案 0 :(得分:3)

请您尝试以下。

arr=($(awk '/background/ && match($0,/\".*\"/){print substr($0,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($0,/\".*\"/){print substr($0,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表示值之间可能存在空格。因此,可能的解决方案可能是通过打印awk命令中的值,并在值之间添加一个新字符(该字符将作为BASH数组迭代的字段分隔符),因此我选择了%命令将给出如下信息(在此处显示的输出中使用测试值)

awk '/background/ && match($0,/\".*\"/){val=val?val "%" substr($0,RSTART+1,RLENGTH-2):substr($0,RSTART+1,RLENGTH-2)} END{print val}' Input_file

singh:test/ bla_bla_bla%singh:bla1/bla2

运行以下命令以创建名为arr的数组。

arr=($(awk '/background/ && match($0,/\".*\"/){val=val?val "%" substr($0,RSTART+1,RLENGTH-2):substr($0,RSTART+1,RLENGTH-2)} END{print val}' Input_file))

现在,如果我们设置IFS='%'并运行以下命令。

echo "${arr[0]}"
singh:test/ bla_bla_bla
echo "${arr[1]}"
singh:bla1/bla2

由于已将新的分隔符用作%,因此不会破坏其中包含空格的值。

答案 1 :(得分:1)

我想我会使用更简单的工具。在这种情况下,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")'

如果您的值包含换行符...那么您就一个人了。 :-)