ela*_*urk 9 command-line text-processing
如何用另一个文件中的字符串随机替换一个文本文件中的特定字符串?例如:
file1.txt(file has more than 200 lines):
moonwalker@address.com
hansolo@address.com
anakinskywalker@address.com
obiwankenobi@address.com
darthvader@address.com
file2.txt(file has 10-20 lines):
@adress1.com
@adress2.com
@adress3.com
@adress4.com
@adress5.com
output.txt:
moonwalker@address4.com
hansolo@address1.com
anakinskywalker@address5.com
obiwankenobi@address2.com
darthvader@address3.com
Run Code Online (Sandbox Code Playgroud)
jan*_*nos 10
你可以实现这个算法:
file2.txt到数组file1.txt:
像这样:
mapfile -t addresses < file2.txt
while IFS='' read -r orig || [[ -n "$orig" ]]; do
((index = RANDOM % ${#addresses[@]}))
name=${orig%%@*}
echo "$name${addresses[index]}"
done < file1.txt
Run Code Online (Sandbox Code Playgroud)
(特别感谢 @GlennJackman 和 @dessert 的改进。)
如果您真的想要随机选择,那么这是使用的一种方法awk:
awk '
BEGIN{FS="@"; OFS=""}
NR==FNR{a[NR]=$0; n++; next}
{$2=a[int(1 + n * rand())]; print}
' file2.txt file1.txt
moonwalker@adress2.com
hansolo@adress2.com
anakinskywalker@adress5.com
obiwankenobi@adress1.com
darthvader@adress3.com
Run Code Online (Sandbox Code Playgroud)
OTOH如果你想要地址的随机排列,我建议像
paste -d '' <(cut -d'@' -f1 file1.txt) <(sort -R file2.txt)
moonwalker@adress2.com
hansolo@adress1.com
anakinskywalker@adress5.com
obiwankenobi@adress4.com
darthvader@adress3.com
Run Code Online (Sandbox Code Playgroud)
您可以使用shuf(您可能需要sudo apt install shuf)将第二个文件的行打乱,然后使用它们来替换:
$ awk -F'@' 'NR==FNR{a[NR]=$1;next}{print a[FNR]"@"$2} ' file1 <(shuf file2)
moonwalker@adress3.com
hansolo@adress1.com
anakinskywalker@adress5.com
obiwankenobi@adress4.com
darthvader@adress2.com
Run Code Online (Sandbox Code Playgroud)
shuf简单地随机化其输入行的顺序。awk那里的命令将首先读取 file1 的所有内容(NR==FNR仅在读取第一个文件时为真),并将第二个字段(字段由 定义@,因此这是域)保存在关联数组中,a其值为域和其键是行号。然后,当我们到达下一个文件时,它会简单地打印存储在a此行号中的任何内容,以及文件 2 中相同行号的内容。
请注意,这假设两个文件的行数完全相同,并且实际上并不是“随机”的,因为它不允许重复任何内容。但这看起来像你想要的。
该解决方案每次都从替换字符串列表的行集中随机选择一个字符串,将输入文件每一行中第一次出现的单个任意给定字符串(“针”)替换为一个字符串。
#!/usr/bin/python
from __future__ import print_function
import sys, random
needle = sys.argv[1]
if sys.argv[2] == '-':
f_replacements = sys.stdin
else:
f_replacements = open(sys.argv[2])
with f_replacements:
replacements = [l.rstrip('\n') for l in f_replacements]
if not replacements:
raise ValueError('No replacement strings given')
if len(sys.argv) <= 3 or sys.argv[3] == '-':
f_in = sys.stdin
else:
f_in = open(sys.argv[3])
with f_in:
for s in f_in:
rep = replacements[random.randrange(len(replacements))]
print(s.rstrip('\n').replace(needle, rep, 1))
Run Code Online (Sandbox Code Playgroud)
将针锚定到字符串的开头或结尾或完全使用正则表达式应该几乎是微不足道的。
python replace-random.py NEEDLE REPLACEMENTS-FILE [INPUT-FILE]
Run Code Online (Sandbox Code Playgroud)
例子:
python replace-random.py '@address.com' file2.txt file1.txt
Run Code Online (Sandbox Code Playgroud)
或者
python replace-random.py '@address.com' file2.txt < file1.txt
Run Code Online (Sandbox Code Playgroud)