Bash:在初始注释后将行插入源代码文件

时间:2011-07-04 22:04:10

标签: bash shell

我需要使用bash将一行插入到python文件中。该行需要在文件中的任何初始注释后出现。

所以给出了文件:

#!/usr/bin/python
# This is just 
# an example comment

moo = "cow"
... etc ...

我需要一个bash命令来插入一个这样的新行:

#!/usr/bin/python
# This is just 
# an example comment
NEW LINE GOES HERE

moo = "cow"
... etc ...

我完全不知道如何做到这一点。我已经尝试逐行循环遍历文件,但这最终变得非常可怕并且严重搞乱了文件的空白。

任何建议都会很棒!

亚当

PS。是的,这是一个奇怪的事情,它是持续集成构建脚本的一部分。


修改

为了记录,我尝试的代码是:

insert_setup_code() {
    installed=false
    tmpfile="/tmp/$RANDOM"

    cat "$INSTALL_TO" | while read -d \n l; do
        echo "$l" >> $tmpfile
        if [[ ! $installed && ! `echo "$l" | grep "^#"` ]]; then
            echo "LINE OF CODE HERE" >> $tmpfile
            installed=true
        fi
    done
}

6 个答案:

答案 0 :(得分:11)

我会写:

line="NEW STUFF HERE"
awk -v text="$line" '!/^#/ && !p {print text; p=1} 1' file

第一个非注释行将触发块打印该行:

  • !/^#/ - 行不以哈希
  • 开头
  • !p - 变量p不正确

答案 1 :(得分:1)

你去了

我的 addline 脚本。在 newline 中的任何初始评论后添加 filein 并写入 fileout

#!/usr/bin/env bash

newline="$1"
filein="$2"
fileout="$3"
added=0

while read -r; do
    if ! ((added)) && ! [[ $REPLY =~ ^# ]]; then
        printf "%s\n" "$newline" >> "$fileout"
        ((added++))
    fi
    printf "%s\n" "$REPLY" >> "$fileout"
done < "$filein"

用作:

$ bash addline "my new line" "readThisFile" "writeToThisFile"

根据您的需要调整:)


自身的示例用法:

$ bash addline "# a test comment line" addline foo
$ cat foo

#!/usr/bin/env bash
# a test comment line

newline="$1"
filein="$2"
fileout="$3"
added=0

while read -r; do
    if ! ((added)) && ! [[ $REPLY =~ ^# ]]; then
        printf "%s\n" "$newline" >> "$fileout"
        ((added++))
    fi
    printf "%s\n" "$REPLY" >> "$fileout"
done < "$filein"

更新的更快版本:
使用wc -lsed编写文件的其余部分而不是遍历每一行

#!/usr/bin/env bash

newline="$1"
filein="$2"
fileout="$3"
counter=0

while read -r; do
    ((counter++))
    if ! [[ $REPLY =~ ^# ]]; then
        printf "%s\n" "$newline" "$REPLY" >> "$fileout"
        break
    fi
    printf "%s\n" "$REPLY" >> "$fileout"
done < "$filein"

sed -n "$counter,$(wc -l < "$filein")p" "$filein" >> "$fileout"

与之前/之上一样工作

答案 2 :(得分:0)

你可以在bash脚本中添加存根,新行和剩余的东西作为变量,即

HEADER="!#/usr/bin/bla bla.."

YOUR_LINE="NEW LINE GOES HERE"

REST="more stuff"

并将它们输入新脚本

echo "$HEADER" "$YOUR_LINE" "$REST" > pytonscript.py

我认为YOUR_LINE变量是动态的,但如果HEADERREST是静态的,那么如果这些变量也是动态的,那么你可以使用head }和tail结合wc -l计算应包含哪些行

答案 3 :(得分:0)

仅供参考,您的bash版本会像这样

insert_setup_code() {
        install_to="$1"
        tmp=$(mktemp -t setup)

        added=0
        while IFS=$'\n' read -r line ; do
                printf "$line\n" >> "$tmp"
                [ $added = 0 ] && grep -q '^#' <<<"$line" && printf "LINE OF CODE HERE\n" >>"$tmp" && added=1
        done < "$install_to"

        mv -f "$tmp" "$install_to"
}

但是,如果您想保留$install_to文件中的元数据

,当然应该采取额外的设置

答案 4 :(得分:0)

找到第一个空行

$ grep -n -m1 '^$' input | cut -d: -f1 
4

使用该行号并将其更改为其他字符串-i以编辑文件(谨慎使用!)

$ sed -i '4c NEW STUFF HERE' input

$ cat input
#!/usr/bin/python
# This is just 
# an example comment
NEW STUFF HERE
moo = "cow"
... etc ...

另一种方法是grep第一行不包含#,然后上面变为:

$ grep -n -m1 '^[^#]' input | cut -d: -f1
5

$ sed -i "5i NEW STUFF HERE" input

$ cat input
#!/usr/bin/python
# This is just 
# an example comment

NEW STUFF HERE
moo = "cow"
... etc ...

要在sed脚本中使用shell变量,请使用此aproach,其中"允许扩展变量

sed "${num}c NEW STUFF HERE" log

答案 5 :(得分:0)

使用ed不需要tmp文件。

以下代码假定在第一个不以#字符开头的非空行之前,只有空行或以#字符开头的行。

# insert a line just before the first line that does not begin with a '#' char
# skips empty lines and lines containing whitespace characters only
# for more information on ed see http://wiki.bash-hackers.org/howto/edit-ed

cat <<-'EOF' | ed -s file
H
/^[[:space:]]*[^#[:space:]]/i
NEW STUFF HERE
.
wq
EOF

如果您坚持在初始评论之后完全插入该行,您也可以这样做。

# using FreeBSD ed (on Mac OS X)
cat <<-'EOF' | ed -s file
H
,v/^#/u\
u\
i\
NEW STUFF HERE\
.
wq
EOF


# using sed & ed
# first get the line number of the first line not beginning with a '#' char;
# then use ed for in-place file editing
lno=$(sed -n '/^#/!{=;q;}' file) &&
cat <<-EOF | ed -s file
H
${lno},${lno}i
NEW STUFF HERE
.
wq
EOF