我有 2 个文本文件。一个是用户名列表以及他们在同一行工作的公司,但以制表符空格分隔。第二个是每周生成的报告的输出,其中包含更多信息。
目标是从每周报告中获取名称,并将其替换为用户名列表中的名称和公司。
用户名和公司列表在 UserList.txt 文件中看起来像这样,其中由制表符空格分隔。
Name1 Company 1
Name2 Company 2
Name3 Company 3
Name4 Company 4
Name5 Company 5
每周输出文件位于 Weekly.txt 文件中
我不知道如何查看第一个文本文件以获取名称和公司名称,并仅替换第二个文本文件中的该部分。
我正在寻找最终的输出,如下所示:
到目前为止,我找到了一种使用sed
命令手动执行此操作的方法。这是我到目前为止所拥有的:
sed -r 's/Name1/Name1 Company 1/g;s/Name2/Name2 Company 2/g;s/Name3/Name3 Company 3/g;s/Name4/Name4 Company 4/g;s/Name5/Name5 Company 5/g'
这是可行的,但它不会读入另一个文件并提取最新信息。请记住,我正在使用 cygwin,这都是更大脚本的一部分。
答案1
使用join
命令:
join -t $'\t' -1 1 -2 2 -o 2.1,1.1,1.2,2.3 \
user_list.txt \
<(sed -E 's/^(loginName:)\s+(\S+)\s+(.*)$/\1\t\2\t\3/' test.txt)
join
-1 1
将使用第一个文件中的第 1 列 ( ) 和第二个文件中的第 2 列 ( )连接两个表-2 2
。它将按照 指定的顺序打印列-o
。
在问题的原始版本中,用户列表采用 XLSX 格式。在这种情况下:
join -t $'\t' -1 1 -2 2 -o 2.1,1.1,1.2,2.3 \
<(xlsx2csv -d tab test.xlsx | tail -n +2) \
<(sed -E 's/^(loginName:)\s+(\S+)\s+(.*)$/\1\t\2\t\3/' test.txt)
在 Debian 上,xlsx2csv
以软件包 ( ) 的形式提供apt install xlsx2csv
。
join
是套餐的一部分coreutils
。
编辑:调整为使用制表符而不是逗号作为分隔符,用户列表以纯文本格式而不是 XLSX 格式显示。
答案2
一种解决方案是对用户文件中的每行进行替换。以下脚本将就地编辑 Weekly.txt:
prefix="loginName:\s*"
tail -n+2 UserList.txt | while read line; do
name=$(printf "$line" | cut -f1)
company=$(printf "$line" | cut -f2 | tr -d '\n')
sed -i "s/^\($prefix\)$name/\1$name $company/g" Weekly.txt
done
为了提高效率,我们可以收集替换内容并执行 sed 一次:
prefix="loginName:\s*"
sedCommand=$(tail -n+2 UserList.txt | while read line; do
name=$(printf "$line" | cut -f1)
company=$(printf "$line" | cut -f2 | tr -d '\n')
printf "s/^\($prefix\)$name/\1$name $company/g;"
done)
sed "$sedCommand" Weekly.txt > new_Weekly.txt
此版本保持Weekly.txt
不变并将结果写入new_Weekly.txt
.