Bash正则表达式查找和替换

时间:2011-09-29 20:14:23

标签: bash sed awk

我不知道这是否可行,但你可以动态改变查找/替换吗? 基本上我有这样的东西

<3 digit number> <data>

我想做的是数据是否匹配

<word>:<4 digit number>

<word>:的所有实例(在整个文件中)替换为行的3位数字I.E:

020 Word
021 Word:0001
Replace with 
020 021
021 0210001

这可以用AWK或Sed吗? 如果没有,它在C中是否可行?

5 个答案:

答案 0 :(得分:3)

我知道这不是你提出的问题,但我认为解决这个问题的最佳方法是使用一个简单的Perl脚本。

#!/usr/bin/perl

$in= "input.txt";
$out= "output.txt";

# Buffer the whole file for replacing:
open(INFILE, $in);
@lines = <INFILE>;
open(INFILE, $in);

# Iterate through each line:
while(<INFILE>) {
  # If the line matches "word:number", replace all instances in the file
  if (/^(\d{3}) (\w+:)\d{4}$/) {
    $num = $1; word = $2;
    s/$word/$num/ foreach @lines;
  }
}

open(OUTFILE, $out);
print OUTFILE foreach @lines;

它看起来比它真正需要的时间长得多,因为我为你做了很好而且易于阅读。

答案 1 :(得分:2)

我希望这次我找到了你。

尝试以下内容:

#file name:t
kent$  cat t
020 Word
021 Word:0001

#first we find out the replacement, 021 in this case:
kent$  v=$(grep -oP "(\d{3})(?= Word:\d{4})" t|head -n1)

#do replace by sed:
kent$  sed -r "s/Word[:]?/$v/g" t                                                                                                        
020 021 
021 0210001

答案 2 :(得分:2)

number=$(gawk --posix '/[0-9]{3} '${word}':[0-9]{4}/ { print $1; exit }' $file)

if [ "$number" != "" ]; then
    sed -r "s/${word}:?/${number}/" $file
fi

答案 3 :(得分:2)

这个awk解决方案需要通过你的文件2次:一次找到需要替换的所有Word,一次实际替换:

gawk '
    NR == FNR {
        if (match($2, /^([^:]+):[0-9][0-9][0-9][0-9]$/, a)) 
            repl[a[1] ":?"] = $1
        next
    }
    {
        for (word in repl)
            if ($2 ~ word) {
                sub(word, repl[word], $2)
                break
            }
        print
    }
' filename filename > new.file

需要gawk来捕捉括号。

答案 4 :(得分:1)

这是另一个sed解决方案:

# sweep the file and make a lookup table variable

lookup=$(sed -nr 's/(.*) (.*:).*/\2\1/p' <source_file |tr '\n' ' ')

# append the lookup to each line and substitute using a backreference
# N.B. remove the lookup whatever!

     sed -r "s/\$/@@${lookup}/;
             s/^(... )(.*)$@@.*\2:(\S*).*/\1\3/;
             s/^(... )(.*:)(.*)@@.*\2(\S*).*/\1\4\3/;
             s/@@.*//" <source_file