在下面的问题中,如果我只是在outfile中写入一个固定字符串,但如果我想使用file1中的随机行而不是固定字符串,那么我就卡住了。我不知道如何将获得随机行的awk代码插入到编辑file2的代码中(或者做同样工作的等效方法(。
文件1:
string1_^%"$"£xxXF%
string2-$^^!dV"$&"}
string3~£""!&vhTT[@
string4_%^c!}[&(SR#
string5_$%&<[*^"!"H
string6_$$£<[*~)!£H
文件2:
@ data1 line1, unique text follows
data1 line2, unique text follows
@ data2 line1, unique text follows
data2 line2, unique text follows
@ data3 line1, unique text follows
data3 line2, unique text follows
@ data4 line1, unique text follows
data4 line2, unique text follows
期望输出:
outfile:
$ data1 line1, unique text follows
data1 line2, unique text follows
fixed_text_inserted
string2-$^^!dV"$&"}
$ data2 line1, unique text follows
data2 line2, unique text follows
fixed_text_inserted
string6_$$£<[*~)!£H
$ data3 line1, unique text follows
data3 line2, unique text follows
fixed_text_inserted
string3~£""!&vhTT[@
$ data4 line1, unique text follows
data4 line2, unique text follows
fixed_text_inserted
string6_$$£<[*~)!£H
fixed_text_inserted总是一样的,只是一个字符串(没有空格或制表符(
每条记录的最后一行(即第4行(是文件1中的一行(这些行包含特殊字符,例如$£%"'%^和文本,但没有空格或制表符(
随机选择是替换,如在我的示例outfile中,其中字符串6_$$£<[*~(!£H}恰好被选中不止一次。
我有大约400个file2,每个都很大(~1GB(,所以我很容易写一个太慢的脚本,但我在用awk实现这一点时遇到了问题。
以下是两个awk命令的想法,每个命令几乎都能完成我想要的一半:
首先从file1:中获取一个随机行
awk 'BEGIN{srand();} {a[NR]=$0} END{for(i=1; i<=5000; i++){x=int(rand()*NR) + 1}}' file 1
然后在从file2:创建新文件(outfile(时使用该随机行
awk 'BEGIN {getline rlines; RS = "#" ; FS = "n"} NR > 1 {print $1"n"$2"n"; printf rlines[NR]; printf "n"}' file2 > outfile
我怀疑将这两条线合并是否是实现这一目标的方法;这些awk线只是给我一个想法(我希望(我正在努力做什么。
我之所以发布这篇文章,不仅是因为我被卡住了,还因为这个问题涉及到如何在awk中处理多个文件以及如何在其中定义复杂变量的一般问题。网上有一些例子,但它们分别对待这些事情。
感谢任何有建议的人,我还没有"糟糕的想法"的感觉。
这将从file1中随机选择一行插入到file2的第三个位置。这对于这项任务来说应该非常快。
$ sed "3i$(shuf -n1 file1)" file2 > file3
如果要每隔三行插入一行,并可能重复随机行,还可以修剪非字母数字边界处的随机字符串。对于多个输入文件重复相同的操作,这应该…
$ awk 'BEGIN {srand()}
NR==FNR {sub(/[^[:alnum:]].*/,""); a[NR]=$0; size++; next}
FNR==1 {close(f); f=FILENAME".outfile"}
{print > f}
!(FNR%2){print a[int(rand()*size)+1] > f}' randomvals file1 file3 ...
首先提供随机值文件,然后提供要更新的文件。将为每个输入文件创建"更新"的附加版本。
听起来可以归结为用第二个文件中的随机行替换一个文件的每三行。使用awk
和shuf
:的组合很容易做到这一点
$ cat file1.txt
#a
b
c
#d
e
f
#g
h
i
$ cat file2.txt
1
2
3
4
5
6
$ awk 'NR == FNR { lines[NR]=$0; next }
{ if (FNR % 3) print; else print lines[++i] }' <(shuf file2.txt) file1.txt
#a
b
6
#d
e
2
#g
h
1
将替换行文件的混洗版本读取到数组中,然后对记录文件的每三行打印一行替换行,而不是原始行。
为了好玩,一个bash等价物使用一个协处理器来访问混洗的文件,而不是将它们存储在数组中。
#!/usr/bin/env bash
# replace.sh originalfile replacementlinesfile
coproc shuf { shuf "$2"; read; }
declare -i i=1
while IFS= read -r line; do
if [ $((i++ % 3)) -eq 0 ]; then
IFS= read -r -u "${shuf[0]}" line
fi
echo "$line"
done < "$1"
echo "done" >&"${shuf[1]}"
wait "$shuf_PID"