我有一个文本文件,其中包含九位数字的列表,如下所示:
550411876
550425175
550426504
第二个文本文件包含如下一行:
09Y20171031 13415520171031 134155AP|AO|ABxxxxxxxxx|AC|CH|BIN|
我需要创建一个文本文件,其中包含第二个文件中多次出现的行,但替换xxxxxxxxx
为第一个文件中的数字(xxxxxxxxx
字面意思是在文件中,这不仅仅是一个示例)。在这种情况下,结果将是:
09Y20171031 13415520171031 134155AP|AO|AB550411876|AC|CH|BIN|
09Y20171031 13415520171031 134155AP|AO|AB550425175|AC|CH|BIN|
09Y20171031 13415520171031 134155AP|AO|AB550426504|AC|CH|BIN|
我该如何在 Linux 中执行此操作?
答案1
假设数字位于文件中numbers
并且您要使用的模板文件是file
:
awk -F'|' -v OFS='|' 'NR==FNR { n[++i] = $0; next } { for (i in n) { $3 = substr($3,1,2) n[i]; print } }' numbers file
这将首先将数字读入 array n
,然后,对于模板文件,使用第三个|
分隔字段中的前两个字符,将其与数组中的数字连接起来n
,并为每个数字打印一次结果。
这些-F'|' -v OFS='|'
选项确保我们都以|
- 分隔的方式读取和写入数据。
然后将其输出重定向到一个新文件中。
这不依赖于模板来包含xxxxxxxxx
。
测试它:
$ cat file
09Y20171031 13415520171031 134155AP|AO|AB something something|AC|CH|BIN|
$ awk -F'|' -v OFS='|' 'NR==FNR { n[++i] = $0; next } { for (i in n) { $3 = substr($3,1,2) n[i]; print } }' numbers file
09Y20171031 13415520171031 134155AP|AO|AB550425175|AC|CH|BIN|
09Y20171031 13415520171031 134155AP|AO|AB550426504|AC|CH|BIN|
09Y20171031 13415520171031 134155AP|AO|AB550411876|AC|CH|BIN|
bash
仅使用 9 个 -es 的方法(无外部实用程序)x
:
template=$(<file)
while read number; do
printf '%s\n' "${template//xxxxxxxxx/$number}"
done <numbers
答案2
显然你的模板只有一行......
如果这是真的我们可以
for a in $(< list)
do
printf "09Y20171031 13415520171031 134155AP|AO|AB%s|AC|CH|BIN|\n" $a
done
答案3
其他awk方法:
awk 'NR==FNR{ a[++c]=$1; next }
{ for(i in a) { r=$0; sub(/x{9}/,a[i],r); print r } }' file1 file2
a[++c]=$1
- 从file1
数组中捕获数字a
for(i in a)
- 迭代九位数字sub(/x{9}/,a[i],r)
- 将关键序列替换xxxxxxxxx
为下一个包含的数量a[i]
输出:
09Y20171031 13415520171031 134155AP|AO|AB550411876|AC|CH|BIN|
09Y20171031 13415520171031 134155AP|AO|AB550425175|AC|CH|BIN|
09Y20171031 13415520171031 134155AP|AO|AB550426504|AC|CH|BIN|
答案4
这里不能缺少Perl。
p=$(< pat) perl -nlE'$l = $ENV{p}; $n=$_; $l =~ s/x{9}/$n/; say $l if /./' nums
pat
是模式文件名
p
是携带模式的环境变量
n
是一个 Perl 变量,包含每次迭代中的数字
l
包含行(首先是每行的模式,然后是替换后要打印的实际行)
nums
是数字文件名