谁能建议如何解决这个问题?假设我有一个文件,并且我想用一些动态值替换匹配行中第一次出现的模式。这里的模式是as
。
源文件:
a b c as aa as
as b d f aa sa
df as kf as df
目标文件:
a b c 1 aa as
2 b d f aa sa
df 3 kf as df
答案1
由于替换模式每次都会改变,这可能更像是 awk 的事情:
awk 'BEGIN { needle=1 } /as/ { $0=gensub( /as/, needle, 1, $0 ); needle=needle+1} { print } ' /path/to/input
以上适用于GNU Awk 4.1.3, API: 1.1 (GNU MPFR 3.1.4, GNU MP 6.1.0)
答案2
如果你真的想使用 sed,这可以在 while 循环内很好地完成:
count=1;
while read line
do sed 's/as/'"$count"'/1' <<< "$line";
count=$((count+1));
done < source_file >> target_file
shell 需要封闭''
的"$count"
对来正确扩展变量以在 sed 命令内使用。
甚至更短(感谢 Kusalananda):
while read line
do sed 's/as/'"$(( ++count ))"'/1' <<< "$line";
done < source_file > target_file
如果您只想在找到模式时增加:
count=1;
while read line;
do sed '/as/! {q100}; s/as/'"$count"'/1' <<< "$line";
[[ "$?" -eq 0 ]] && (( ++count ));
done < source_file > target_file
答案3
和perl
$ perl -pe 'BEGIN{$n=1} s/as/$n++/e' file
a b c 1 aa as
2 b d f aa sa
df 3 kf as df
答案4
这是一个小的 python 脚本,可以满足您的要求。
#!/usr/bin/env python
import sys
counter = 0
with open(sys.argv[1]) as fd:
for line in fd:
new_words = []
words = line.strip().split()
found = False
for word in words:
val = word
if word == 'as' and not found:
counter += 1
found = True
val = str(counter)
new_words.append(val)
print(" ".join(new_words))
并进行测试运行:
$ ./substitute_dynamic_val.py input.txt
a b c 1 aa as
2 b d f aa sa
df 3 kf as df