我在 Linux 机器上有 2 个包含数据的文件(mac
和uid
),我想将它们转移到带有列表的“模板”中,用于sed
用变量替换数据。
列表.txt:
CP00
CP01
mac.txt:
FF-AA-BB-AA-DD-AA
00-AA-11-AA-11-EE
uid.txt:
e3442342a
e43342f0a
模板:
#Template for Cobbler:
"uid": "change1",
"mac_address": "change2",
我需要 2 个带有模板的文件(第一个文件包含第一个“uid”和第一个“mac”,第二个文件包含第二个“uid”和第二个“mac”)。
我正在尝试这个,但它不起作用:
change1=$(cat /tmp/cobbler/uid.txt);
change2=$(cat /tmp/cobbler/mac.txt);
for i in `cat /tmp/cobbler/list.txt`; do
echo $i | cat /tmp/cobbler/template |
sed -e "s/change1/$change1/g" -e "s/change2/$change2/g" >> /tmp/cobbler/$i;
done
结果组合了列表的 2 个名称CP00CP01
,并且仅放入第一个“uid”和第一个“mac”。
有人能帮我吗?谢谢!
答案1
使用任何 awk:
$ cat tst.sh
#!/usr/bin/env bash
cd /tmp/cobbler &&
awk '
FILENAME == ARGV[1] { uids[FNR] = $1 }
FILENAME == ARGV[2] { macs[FNR] = $1 }
FILENAME == ARGV[3] { outs[FNR] = $1 }
FILENAME == ARGV[4] {
for ( outNr in outs ) {
if ( $1 == "\"uid\":" ) {
$2 = "\"" uids[++uidNr] "\","
}
if ( $1 == "\"mac_address\":" ) {
$2 = "\"" macs[++macNr] "\","
}
print > (outs[outNr] ".txt")
}
}
' uid.txt mac.txt list.txt template
$ ./tst.sh
$ head /tmp/cobbler/CP*
==> /tmp/cobbler/CP00.txt <==
#Template for Cobbler:
"uid": "e3442342a",
"mac_address": "FF-AA-BB-AA-DD-AA",
==> /tmp/cobbler/CP01.txt <==
#Template for Cobbler:
"uid": "e43342f0a",
"mac_address": "00-AA-11-AA-11-EE",
答案2
由于各种原因,这不起作用。首先,change1=$(cat /tmp/cobbler/uid.txt);
将 的全部内容/tmp/cobbler/uid.txt
放入一个变量中:
$ echo "$change1"
e3442342a
e43342f0a
那不是你想要的。接下来,echo $i | cat /tmp/cobbler/template
毫无意义,因为cat
给出了一个文件,因此它将忽略其标准输入并简单地打印出文件的内容,忽略$i
.无论如何,for i in `cat file`; do...
这是不好的做法,不要使用它!看Bash 陷阱 #1。
如果我正确理解了您的需求,这应该会为您提供您想要的输出:
c=1
while read change1; do
listName=$(awk -v lnum="$c" 'NR==lnum' list.txt)
change2=$(awk -v lnum="$c" 'NR==lnum' mac.txt)
sed "s/change1/$change1/; s/change2/$change2/" template > "$listName".txt
(( c++ ))
done < uid.txt
解释
c=1
:这是我们的变量,用于跟踪我们正在查看的行。在循环(( c++ ))
的每次迭代结束时它都会增加一 ( )while
。while read change1; do ... ; done < uid.txt
:迭代 的每一行uid.txt
,将每一行保存为$change1
.listName=$(awk -v lnum="$c" 'NR==lnum' list.txt)
: 用于awk
打印$lnum
的第 行list.txt
。我们将$c
(我们的计数器)的值传递给awk
awk 变量lnum
。然后,awk
如果当前行号 ( ) 与( )NR
相同,则打印该行。最后,我们将此行存储为.lnum
NR==lnum
$listName
change2=$(awk -v lnum="$c" 'NR==lnum' mac.txt)
:与上面相同,但是这次我们$chahge2
通过从 中获取相应的行来存储mac.txt
。sed "s/change1/$change1/; s/change2/$change2/" template > "$listName".txt
sed
:在 上运行命令template
,进行所需的替换,并将输出保存到名为$listName.txt
.
在您的示例数据上,结果如下:
$ ls
CP00.txt CP01.txt list.txt mac.txt template uid.txt
$ cat CP00.txt
#Template for Cobbler:
"uid": "e3442342a",
"mac_address": "FF-AA-BB-AA-DD-AA",
$ cat CP01.txt
#Template for Cobbler:
"uid": "e43342f0a",
"mac_address": "00-AA-11-AA-11-EE",