如何使用sed根据每场比赛替换每场比赛?

时间:2016-06-19 07:30:15

标签: regex linux awk replace sed

$ echo 'a,b,c,d=1' | sed '__MAGIC_HERE__'
a=1,b=1,c=1,d=1
$ echo 'a,b,c,d=2' | sed '__MAGIC_HERE__'
a=2,b=2,c=2,d=2

剂量sed可以施放此法术吗?

修改

我必须使用sed两次来实现这个

s='a,b,c,d=2'
v=`echo $s | sed -rn 's/.*([0-9]+)/\1/p'`
echo $s | sed "s/=.*//" | sed -rn "s/([a-z])/\1=$v/gp"

OR

s='a,b,c,d=2'
echo $s | sed -rn 's/.*([0-9]+)/\1/p' | { read v;echo $s | sed "s/=.*//" | sed -rn "s/([a-z])/\1=$v/gp"; }

修改

真实用例是here并且有多行内容,感谢@ hek2mgl,awk更容易。

修改

我的用例

export LS_COLORS='no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:ex=01;32'


exts="
tar|tgz|arj|taz|lzh|zip|z|Z|gz|bz2|deb|rpm|jar=01;31
jpg|jpeg|gif|bmp|pbm|pgm|ppm|tga|xbm|xpm|tif|tiff|png=01;34
mov|fli|gl|dl|xcf|xwd|ogg|mp3|wav=01;35
flv|mkv|mp4|mpg|mpeg|avi=01;36
"

# SED Version

read -rd '' exts < <(
for i in $(echo $exts)
do
  echo $i | sed -rn 's/.*=(.*)/\1/p' | { read v; echo $i | sed "s/=.*//" | sed -rn "s/([^|]+)\|?/:\*.\1=$v/gp"; }
done | tr -d '\n'
)
export LS_COLORS="$LS_COLORS$exts"

# AWK Version
read -r -d '' exts < <( echo $exts | xargs -n1 | awk -F= '{gsub(/\|/,"="$2":*.")}$2' | tr "\n" ":" )
export LS_COLORS="$LS_COLORS:*.$exts"

unset exts

修改

Finale sed version

read -r -d '' exts < <( echo $exts | xargs -n1 | sed -r 's/\|/\n/g;:a;s/\n(.*(=.*))/\2:*.\1/;ta' | sed "s/^/*./g" | tr "\n" ":" )
export LS_COLORS="$LS_COLORS:$exts"

5 个答案:

答案 0 :(得分:3)

我会使用awk

awk -F= '{gsub(/,/,"="$2",")}1'

-F=将输入行拆分为=,我们可以访问第二个字段$2中的数字。 gsub()将所有,替换为=$2,。最后的1awk成语。它只会打印修改过的行。

答案 1 :(得分:3)

这可能适合你(GNU sed):

sed -r 's/,/\n/g;:a;s/\n(.*(=.*))/\2,\1/;ta' file

将分隔符转换为换行符(文件中找不到的唯一字符),然后用所需的字符串和原始分隔符替换换行符的每个匹配项。

答案 2 :(得分:1)

Perl可以......

echo 'a,b,c,d=1' | perl -ne 'chomp; my ($val) = m|=(\d+)|; s|\=.*||; print join(",", map {"$_=$val"} split/,/) . "\n";'
a=1,b=1,c=1,d=1

<强>解释

perl -ne                  # Loop over input and run command
chomp;                    # Remove trailing newline
my ($val) = m|=(\d+)|;    # Find numeric value after '='
s|\=.*||;                 # Remove everything starting with '='
split /,/                 # Split input on ',' => ( a, b, c, d )
map {"$_=$val" }          # Create strings ( "a=1", "b=1", ... ) from results of split
join(",",...)             # Join the results of previous map with ','
print .... "\n"           # Print it all out with a newline at the end.

答案 3 :(得分:1)

我希望你不会在你的代码中认真使用read / echo / xargs / sed / sed / tr。只需使用一个简单的小型awk脚本:

$ cat tst.sh
exts="
tar|tgz|arj|taz|lzh|zip|z|Z|gz|bz2|deb|rpm|jar=01;31
jpg|jpeg|gif|bmp|pbm|pgm|ppm|tga|xbm|xpm|tif|tiff|png=01;34
mov|fli|gl|dl|xcf|xwd|ogg|mp3|wav=01;35
flv|mkv|mp4|mpg|mpeg|avi=01;36
"

exts=$( awk -F'=' '
    NF {
        gsub(/\||$/, "="$2":", $1)
        out = out $1
    }
    END {
        sub(":$", "", out)
        print out
    }
' <<<"$exts" )

echo "$exts"

$ ./tst.sh
tar=01;31:tgz=01;31:arj=01;31:taz=01;31:lzh=01;31:zip=01;31:z=01;31:Z=01;31:gz=01;31:bz2=01;31:deb=01;31:rpm=01;31:jar=01;31:jpg=01;34:jpeg=01;34:gif=01;34:bmp=01;34:pbm=01;34:pgm=01;34:ppm=01;34:tga=01;34:xbm=01;34:xpm=01;34:tif=01;34:tiff=01;34:png=01;34:mov=01;35:fli=01;35:gl=01;35:dl=01;35:xcf=01;35:xwd=01;35:ogg=01;35:mp3=01;35:wav=01;35:flv=01;36:mkv=01;36:mp4=01;36:mpg=01;36:mpeg=01;36:avi=01;36

答案 4 :(得分:0)

Perl,另一种Perl替代方案......

<强> d = 1:

echo 'a,b,c,d=1' | perl -pe '($a)=/(\d+)$/; s/,/=$a,/g;'
a=1,b=1,c=1,d=1

<强> d = 2:

echo 'a,b,c,d=2' | perl -pe '($a)=/(\d+)$/; s/,/=$a,/g;'
a=2,b=2,c=2,d=2

<强>说明:

perl -e                  # perl one-liner switch
perl -ne                 # puts an implicit loop for each line of input
perl -pe                 # as 'perl -ne', but adds an implicit print at the end of each iteration
($a)=/(\d+)$/;           # catch the number in d=1 or d=2, assign variable $a
s/,/=$a,/g;              # substitute each ',' with '=1,' if $a=1