我有两个文件,每个文件的数据排列在两列中。列之间用分号分隔。第一个文件(11_19.txt)包含更多行,第二个文件(12_19.txt)用于更新第一个文件。第一部分中的每一行都有一个 id,因此如果脚本在两个文件中找到具有相同 id 的行,则应使用第二个文件中的数据更新第一个文件。
假设第一个文件是这样的:
$ cat 11_19.txt
id=123;112233
id=456;445566
id=789;778899
id=000;000000
第二个文件是这样的:
$ cat 12_19.txt
id=123;123123
id=000;999999
脚本的预期结果:
$ ./script.sh 11_19 12_19
11_19
id=123;123123
id=456;445566
id=789;778899
id=000;999999
我尝试将 csv 的一部分转换为数组,但无法使其工作。
id=($(cut -f1 -d, $2))
info=($(cut -f2 -d, $2))
for id in ${id[@]}; do
if grep "$id" $1; then
sed -E s/id="$id";.*/id="$id";$info"/ $1>$1
else
:
fi
done
其次,我想使用第二个文件来更改具有不同扩展名的不同文件(例如 html 文件)的值,并在第二个文件中添加第二个值,其中 id 在 html 文件中匹配。
<!DOCTYPE html>
<html>
<body>
...
<p1 id=123></p1>
预期输出:
<!DOCTYPE html>
<html>
<body>
...
<p1 id=123>123123</p1>
答案1
[编辑:我用于data1
OP 的文件11_19.txt
和data2
OP 的文件12_19.txt
]
笔记:如图所示,在对第一列执行 JOIN 之前,需要在各自的第一列上对 data1 和 data2 进行排序。
$ cat data1
id=123;112233
id=456;445566
id=789;778899
id=000;000000
$ cat data2
id=123;123123
id=000;999999
然后发出:
$ sed -E 's/\;.*\;/;/' <(join -a1 -j 1 -t";" <(sort data1) <(sort data2))
id=000;999999
id=123;123123
id=456;445566
id=789;778899
或等效的(结果):
$ join -a1 -j 1 -t";" <(sort data1) <(sort data2) | sed -E 's/\;.*\;/;/'
id=000;999999
id=123;123123
id=456;445566
id=789;778899
man join
,man sed
并info sed
在终端中将为您提供上述单行代码中使用的各种选项的含义。
答案2
简单的bash
脚本:
$ cat script.sh
!/bin/bash
file1=$1
file2=$2
while IFS=';' read a b
do
r="$b"
while IFS=';' read c d
do
if [ "$a" == "$c" ]
then
r="$d"
fi
done < $file2
printf "%s;%s\n" $a $r
done < $file1
$ ./script.sh 11_19 12_19
id=123;123123
id=456;445566
id=789;778899
id=000;999999
$
注意 - 脚本中没有错误检查,并且不会覆盖原始文件。