简体   繁体   English

在shell脚本中转​​义sed

[英]escape sed in shell script

I wish to put some numbers in my result txt files using shell script and sed, like: 我希望使用Shell脚本和sed在结果txt文件中添加一些数字,例如:

for i in 0.88 0.90 0.92 0.94 0.96 0.98 1.00 1.02 1.04 1.06 1.08 1.10 1.12; do
    a_original_A=5
    amod=`bc <<< "$i*$a_original_A"`
    sed -s -i '1i|/\"list_number_$i  $amod  $amod  $amod  90  90  90" ' list_${i}.txt
    sed -s -i '1i\12' list_${i}.txt
done

But it didn't work. 但这没有用。 I tried to use sed with escaping, but failed; 我尝试使用sed进行转义,但是失败了。 I tried 我试过了

sed -s -i '1i|/\"list_number_$i  ${amod}  ${amod}  ${amod}  90  90  90" ' list_${i}.txt

But this doesn't help as well. 但这也无济于事。

Here, I wish to make 13 number of txt files, and wish to put changing numbers at the second line of 13 txt files. 在这里,我希望制作13个txt文件,并希望将更改的数字放在13个txt文件的第二行。 For example, list_0.88.txt contains 例如,list_0.88.txt包含

12
list_number_0.88    4.4   4.4   4.4   90   90   90

Those two lines at the beginning of the file. 文件开头的那两行。 4.4 is coming from 5*0.88. 4.4来自5 * 0.88。 Likewise, I wish to make 13 files, to have different numbers in 2nd line. 同样,我希望制作13个文件,在第二行中使用不同的编号。 How can I use numbers in sed command? 如何在sed命令中使用数字?

NB: There are already 13 non-empty text files; 注意:已经有13个非空的文本文件; I wish to add these new lines as the first two lines in each of the existing files. 我希望将这些新行添加为每个现有文件中的前两行。

First , you have "list_0.88.txt , list_0.90.txt ... " , and so on , right ? 首先,您有“ list_0.88.txt,list_0.90.txt ...”,依此类推,对吧? As your wish , I think we can modify the shell like that: 如您所愿,我认为我们可以像这样修改shell:

#!/bin/bash

for i in "0.88 0.90 0.92 0.94 0.96 0.98 1.00 1.02 1.04 1.06 1.08 1.10 1.12"
do
        a_original_A=5
        amod=`bc <<< "$i*$a_original_A"`
        echo "---->$amod"
        echo "12" > /tmp/tmpfile
        echo "list_number_$i  $amod  $amod  $amod  90  90  90" >> /tmp/tmpfile
        cat list_${i} >> /tmp/tmpfile
        cp -rf list_${i}.txt list_${i}.txt.bak
        cp -rf /tmp/tmpfile list_${i}.txt
done

What on earth are you doing trying to use shell plus sed plus bc for this??? 您到底要做什么使用shell plus sed plus bc? The general purpose UNIX text manipulation tool is awk: 通用UNIX文本操作工具为awk:

awk 'BEGIN {
    a_original_A = 5
    split("0.88 0.90 0.92 0.94 0.96 0.98 1.00 1.02 1.04 1.06 1.08 1.10 1.12",nums)
    for (i in nums) {
        num = nums[i]
        out = "list_" num ".txt"
        amod = num * a_original_A
        print "12" > out
        print "list_number_" num, amod, amod, amod, 90, 90, 90" > out
        close(out)
    }
}'

wrt your comment below, if you already have files in your directory then with GNU awk (which I assume you have since you're using GNU sed in your example) it'd be: 在下面发表您的评论,如果您的目录中已经有文件,则使用GNU awk(假设您在示例中使用的是GNU sed,我假设您已经有了),它将是:

awk -i inplace '
BEGIN { a_original_A = 5 }
FNR==1 {
    num = gensub(/.*_/,"",1,FILENAME)
    amod = num * a_original_A
    print "12"
    print "list_number_" num, amod, amod, amod, 90, 90, 90"
}
{ print }
' list_*.txt

There are many possible ways to do this. 有很多可能的方法可以做到这一点。 This code uses the seq command to generate the range of numbers. 此代码使用seq命令生成数字范围。 It comes in 3 parts. 它分为3部分。 The first part creates the 'pre-existing' files. 第一部分创建“现有”文件。

The second part shows two ways of editing the files. 第二部分显示了两种编辑文件的方法。 The version with the line (tag) 12A doesn't require support for -i from sed (it isn't standard, and the behaviour of GNU sed is different from the behaviour of BSD (Mac OS X) sed ). 带有(标记)行12A的版本不需要从sed支持-i (它不是标准的,并且GNU sed的行为不同于BSD(Mac OS X) sed的行为)。 The version with the line (tag) 12B uses classical sed notation (which works with both GNU sed and other variants) to insert two lines of information before line 1 of the original text in the file. 带有行(标签) 12B的版本使用经典的sed表示法(与GNU sed和其他变体一起使用)在文件中原始文本的第1行之前插入两行信息。

# Generate 'pre-existing' files
for number in $(seq -f '%4.2f' 0.88 0.02 1.12)
do echo "Pre-existing data in file $number" > list_$number.txt
done

tmp=$(mktemp ./tmp.XXXXXX)
trap "rm -f $tmp; exit 1" 0 1 2 3 13 15

for number in $(seq -f '%4.2f' 0.88 0.02 1.12)
do
    list="list_$number.txt"

    # Works without using sed
    {
    echo "12A"
    echo "$number" | awk '{ x=5*$1; printf("list_number_%4.2f %4.1f %4.1f %4.1f 90 90 90\n", $1, x, x, x) }'
    cat "$list"
    } > "$tmp"
    cp "$tmp" "$list"
    rm -f "$tmp"

    # Option 2 (as written, works with GNU sed and BSD sed)
    amod=$(echo "$number" | awk '{printf "%4.1f\n", 5*$1}')
    sed -i.bak -e "1i\\
    12B\\
    list_number_$number $amod $amod $amod 90 90 90" "$list"

done

trap 0 1 2 3 13 15

Sample output ( cat list_1.1?.txt ): 样本输出( cat list_1.1?.txt ):

12B
list_number_1.10  5.5  5.5  5.5 90 90 90
12A
list_number_1.10  5.5  5.5  5.5 90 90 90
Pre-existing data in file 1.10
12B
list_number_1.12  5.6  5.6  5.6 90 90 90
12A
list_number_1.12  5.6  5.6  5.6 90 90 90
Pre-existing data in file 1.12

Obviously, the code assumes you have seq , but it is available as part of GNU CoreUtils and on Mac OS X. 显然,代码假定您具有seq ,但是它可以作为GNU CoreUtils的一部分以及在Mac OS X上使用。

Another technique altogether: 另一个技术:

# Generate pre-existing files as before
for number in $(seq -f '%4.2f' 0.88 0.02 1.12)
do echo "Pre-existing data in file $number" > list_$number.txt
done

# Generate the two parameters from awk; use sed to edit each file in turn.
awk 'BEGIN { for (i = 0.88; i <= 1.12; i += 0.02) printf "%4.2f %4.1f\n", i, 5*i }' |
while read number amod
do
    list="list_$number.txt"
    sed -i.bak -e "1i\\
    12\\
    list_number_$number $amod $amod $amod 90 90 90" "$list"
done

Sample output ( cat list_1.1?.txt ): 样本输出( cat list_1.1?.txt ):

12
list_number_1.10 5.5 5.5 5.5 90 90 90
Pre-existing data in file 1.10
12
list_number_1.12 5.6 5.6 5.6 90 90 90
Pre-existing data in file 1.12

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM