我有一个文件 example.txt,其中包含多行:
Larry is funny!
Funny, I've no glue!
Look here!
Tom has no pants.
The underpants are in the drawer.
Pants are in the closet!
创建具有 4 个随机行号的文件后
sed -n '=' example.txt | shuf | head -3 > line_numbers.txt
假设 line_numbers.txt 中的行号包含
1
3
6
我想通过在 line_numbers.txt 的每一行附加单词 WORD 来编辑 example.txt,其中包含完整的单词“pants”(而不是像“underpants”这样的部分单词)。
我怎样才能做到这一点?
我希望 example.txt 看起来像这样
Larry is funny!
Funny, I've no glue!
Look here!
Tom has no pants.
The underpants are in the drawer.
Pants are in the closet!WORD
编辑:
要仅查找完整单词,您必须像这样编写您的 source_word \<source_word\>
。
其他可能的例子:
我有另一个文件包含这些行:
I love apples.
You hate pineapples.
Apple pie is delicious.
Why do you do not like eating an apple?
We prefer pears to apples.
How many apples do you want to eat?
I have to bake three apple pies for sunday.
我有一个包含三个随机行号的列表
6
2
4
我只想在每行末尾添加--OK
(如果该行包含完整的单词)apples
。
输出必须如下所示:
I love apples.
You hate pineapples.
Apple pie is delicious.
Why do you do not like eating an apple?
We prefer pears to apples.
How many apples do you want to eat?--OK
I have to bake three apple pies for sunday.
答案1
我希望也有办法sed
,但就我个人而言,我发现awk
这种更复杂的操作要容易得多:
awk 'NR==FNR{a[$1]++; next}
{
s=tolower($0);
if(FNR in a && s~/pants/){$0=$0"WORD"}
}1' line_numbers.txt examples.txt
Larry is funny!
Funny, I've no glue!
Look here!
Tom has no pants.
The underpants are in the drawer.
Pants are in the closet!WORD
如果您有 GNU awk
(gawk
Linux 系统上的默认设置),您可以执行以下操作来就地编辑文件:
gawk -i inplace 'NR==FNR{a[$1]++; print; next}
{
s=tolower($0);
if(FNR in a && s~/pants/){$0=$0"WORD"}
}1' line_numbers.txt examples.txt
或者,如果您不介意丢失以下内容,则稍微简单一些line_numbers.txt
:
gawk -i inplace 'NR==FNR{a[$1]++; next}
{
s=tolower($0);
if(FNR in a && s~/pants/){$0=$0"WORD"}
}1' line_numbers.txt examples.txt
答案2
以下管道是您的修改版,输出sed
执行您编辑的脚本:
sed -n '=' file | shuf -n 3 | sed 's,$, { /\\<pants\\>/ s/$/WORD/; },'
或者,等价地,
awk '{ printf "%d { /\\<pants\\>/ s/$/WORD/; }\n", NR }' file | shuf -n 3
例如,这可以生成
6 { /\<pants\>/ s/$/WORD/; }
5 { /\<pants\>/ s/$/WORD/; }
1 { /\<pants\>/ s/$/WORD/; }
如果该模式出现在任何随机选择的行上,则此脚本会应用替换,该替换会WORD
在与模式匹配的每行末尾添加。pants
运行它只需使用以下命令读取它sed -f
:
sed -n '=' example.txt | shuf -n 3 | sed 's,$, { /\\<pants\\>/ s/$/WORD/; },' |
sed -i -f /dev/stdin example.txt
或者,使用基于我的awk
变体:
awk '{ printf "%d { /\\<pants\\>/ s/$/WORD/; }\n", NR }' example.txt | shuf -n 3 |
sed -i -f /dev/stdin example.txt
不需要中间文件。
替换pants
为apples
和WORD
with--OK
以解决您更新的查询。
答案3
这是一个单行(虽然有点长!)。
假设你的文本文件是“tfile”,索引文件是ifile,那么:
awk 'BEGIN{i=0;p=0}{if(FNR==NR){a[i++]=$1} else {if(a[p]==FNR){p++;g="";if(index($0,"Pants")){g="WORD"}; print $0,g}else{print $0}}}' ifile tfile
你会得到:
Larry is funny!
Funny, I've no glue!
Look here!
Tom has no pants.
The underpants are in the drawer.
Pants are in the closet! WORD
答案4
使用 GNU sed,我们可以从行号文件构造 sed 代码并将它们应用到数据文件上:
sed -f - <<\eof line_numbers.txt |\
sed -f - example.txt
1i /pants/I!b
s/$/ba/
$a b;:a;s/$/WORD/
eof
另一种方法是我们按行号转录 sed 命令
sed -e 's:.*:&s/pants.*/\&WORD/I;t:' line_numbers.txt |
sed -f /dev/stdin example.txt