我需要使用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
}
答案 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 -l
和sed
编写文件的其余部分而不是遍历每一行
#!/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
变量是动态的,但如果HEADER
和REST
是静态的,那么如果这些变量也是动态的,那么你可以使用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