bash:replace文本文件中的整行
我有一个情况,我想要一个bash脚本来replace文件中的整个行。 行号总是相同的,所以可以是一个硬编码的variables。
我不是要replace那一行中的一些子string,我只是想用一个新行来完全replace这一行。
是否有任何bash方法来做到这一点(或简单的可以扔到.sh脚本中)。
不是最大的,但这应该工作:
sed -i 'Ns/.*/replacement-line/' file.txt
N
应该由您的目标行号代替。 这将replace原始文件中的行。 要将更改的文本保存在其他文件中,请删除-i
选项:
sed 'Ns/.*/replacement-line/' file.txt > new_file.txt
我实际上使用这个脚本来replace我们公司的UNIX服务器上的cron文件中的一行代码。 我们像普通的shell脚本那样执行它,并没有任何问题:
#Create temporary file with new line in place cat /dir/file | sed -e "s/the_original_line/the_new_line/" > /dir/temp_file #Copy the new file over the original file mv /dir/temp_file /dir/file
这不是行号,但是你可以很容易的切换到一个基于行号的系统,把行号放在s/
之前,并且放置一个通配符来代替the_original_line
。
假设你想用“不同”的文字replace第4行。 你可以像这样使用AWK:
awk '{ if (NR == 4) print "different"; else print $0}' input_file.txt > output_file.txt
AWK认为input是“logging”,分为“字段”。 默认情况下,一行是一条logging。 NR
是所看到的logging数量。 $0
表示当前的完整logging(而$1
是logging中的第一个字段等等,默认情况下字段是行中的单词)。
所以,如果当前的行号是4,打印string“不同”,但不改变打印行。
在AWK中,封装在{ }
程序代码在每个inputlogging上运行一次。
您需要用单引号引用AWK程序,以防止shell试图解释$0
类的东西。
编辑:从下面的评论中@chepner更短,更优雅的AWK程序:
awk 'NR==4 {$0="different"} { print }' input_file.txt
仅用于logging(即行)编号4,用string“不同”replace整个logging。 然后为每个inputlogging打印logging。
很明显,我的AWK技能很生疏! 谢谢@chepner。
编辑:也见@Dennis Williamson更短的版本:
awk 'NR==4 {$0="different"} 1' input_file.txt
这是如何工作的在评论中解释: 1
总是评估真,所以相关的代码块总是运行。 但没有关联的代码块,这意味着AWK只是打印整行的默认行为。 AWK旨在允许这样简洁的程序。
鉴于这个testing文件(test.txt)
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis eu diam non tortor laoreet bibendum vitae et tellus.
以下命令会将第一行replace为“换行符”
$ sed '1 c\ > newline text' test.txt
结果:
newline text consectetur adipiscing elit. Duis eu diam non tortor laoreet bibendum vitae et tellus.
更多信息可以在这里find
http://www.thegeekstuff.com/2009/11/unix-sed-tutorial-append-insert-replace-and-count-file-lines/
在bash中,用行号和xxx yyy来代替N,M
i=1 while read line;do if((i==N));then echo 'xxx' elif((i==M));then echo 'yyy' else echo "$line" fi ((i++)) done < orig-file > new-file
编辑
实际上在这个解决scheme中有一些问题,用字符“\ 0”“\ t”和“\”
“\ t”,可以通过在读取之前放入IFS =“\”来解决,在行结尾用-r
IFS= read -r line
但是对于“\ 0”,variables被截断,在纯bash中没有解决scheme: 将包含空字符(\ 0)的string赋值给Bash中的variables但是在普通文本文件中没有nul字符\ 0
perl将是一个更好的select
perl -ne 'if($.==N){print"xxx\n"}elsif($.==M){print"yyy\n"}else{print}' < orig-file > new-file
Chepner的优秀答案。 它在bash Shell中为我工作。
# To update/replace the new line string value with the exiting line of the file MyFile=/tmp/ps_checkdb.flag `sed -i "${index}s/.*/${newLine}/" $MyFile`
这里
index
– 行号
newLine
– 我们要replace的新行string。
同样,下面的代码用于读取文件中的特定行。 这不会影响实际的文件。
LineString=`sed "$index!d" $MyFile`
这里
!d
– 将删除行以外的行no $index
因此,我们将在文件中得到输出为无$index
行string。
# Replace the line of the given line number with the given replacement in the given file. function replace-line-in-file() { local file="$1" local line_num="$2" local replacement="$3" # Escape backslash, forward slash and ampersand for use as a sed replacement. replacement_escaped=$( echo "$replacement" | sed -e 's/[\/&]/\\&/g' ) sed -i "${line_num}s/.*/$replacement_escaped/" "$file" }