如何用行号替换文本文件中的整行

这种情况下,我需要一个bash脚本来替换文件中的整行。 行号始终相同,因此可以是硬编码变量。

我并没有试图替换该行中的某个子字符串,我只是想用一个新行完全替换该行。

有没有什么bash方法可以做到这一点(或者一些简单的方法可以放到.sh脚本中)?

358220 次浏览

不是最好的,但这应该是可行的:

sed -i 'Ns/.*/replacement-line/' file.txt

其中,N应替换为目标行号。这将替换原始文件中的行。要将更改的文本保存在其他文件中,请删除“-i ”选项:

sed 'Ns/.*/replacement-line/' file.txt > new_file.txt

假设你想用文本“ different”替换第4行,你可以这样使用 AWK:

awk '{ if (NR == 4) print "different"; else print $0}' input_file.txt > output_file.txt

AWK 认为输入是“记录”,分为“字段”。默认情况下,一行就是一条记录。NR是看到的记录数。$0表示当前完整的记录(而 $1是记录中的第一个字段,以此类推; 默认情况下,这些字段是该行中的单词)。

因此,如果当前行号为4,则打印字符串“ different”,但在其他情况下不打印该行。

在 AWK 中,包含在 { }中的程序代码在每个输入记录上运行一次。

您需要用单引号引用 AWK 程序,以防止 shell 尝试解释诸如 $0之类的内容。

编辑:@chepner 的一个更短更优雅的 AWK 程序在下面的评论中写道:

awk 'NR==4 {$0="different"} { print }' input_file.txt

仅对于记录(即第4行) ,将整个记录替换为字符串“ different”。然后,对于每个输入记录,打印该记录。

很明显我的 AWK 技术生疏了! 谢谢你,@Chepner。

编辑: 还可以看到@Dennis Williamson 的一个更短的版本:

awk 'NR==4 {$0="different"} 1' input_file.txt

注释中解释了这是如何工作的: 1始终计算为 true,因此相关的代码块始终运行。但是没有相关的代码块,这意味着 AWK 默认只打印整行代码。AWK 就是为这样的简洁程序而设计的。

在 bash 中,将 N、 M 替换为行号,将 xxx yyy 替换为所需的值

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

剪辑

事实上,在这个解决方案中有一些问题,字符“0”“ t”和“”

“ t”,可以在阅读前加上 IFS = 来解决: 以“ r”结尾的

IFS= read -r line

但是对于“0”,变量被截断,在纯 bash 中没有解决方案: 将包含空字符(0)的字符串分配给 Bash 中的变量 但是在普通文本文件中没有空字符0

Perl 是一个更好的选择

perl -ne 'if($.==N){print"xxx\n"}elsif($.==M){print"yyy\n"}else{print}' < orig-file > new-file

给定这个测试文件(test.txt)

Lorem ipsum dolor sit amet,
consectetur adipiscing elit.
Duis eu diam non tortor laoreet
bibendum vitae et tellus.

以下命令将第一行替换为“ newline text”

$ sed '1 c\
> newline text' test.txt

结果:

newline text
consectetur adipiscing elit.
Duis eu diam non tortor laoreet
bibendum vitae et tellus.

你可在此找到更多资料

Http://www.thegeekstuff.com/2009/11/unix-sed-tutorial-append-insert-replace-and-count-file-lines/

不久前,我实际上使用这个脚本替换了我们公司 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的位置。

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-我们要替换的新行字符串。


类似地,下面的代码用于读取文件中的特定行。这不会影响实际的文件。

LineString=`sed "$index!d" $MyFile`

给你
将删除除行以外的其他行没有 $index 因此,我们将在文件中以行字符串的形式获得没有 $index的输出。

# 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"
}

您甚至可以将参数传递给 sed 命令:

Test.sh

#!/bin/bash
echo "-> start"
for i in $(seq 5); do
# passing parameters to sed
j=$(($i+3))
sed -i "${j}s/.*/replaced by '$i'!/" output.dat
done
echo "-> finished"
exit

原始输出数据:

a
b
c
d
e
f
g
h
i
j

执行 ./test.sh会得到新的 output.dat

a
b
c
replaced by '1'!
replaced by '2'!
replaced by '3'!
replaced by '4'!
replaced by '5'!
i
j

我在 Mac 上用过

sed -i '' -e 's/text-on-line-to-be-changed.*/text-to-replace-the=whole-line/' file-name

sed c\代替线路

参考文献

sed c\实际上不会更改文件,因此您需要将其输出发送到一个临时文件,然后 cat将临时文件发送到原始文件。不需要匹配模式,因为我们可以指定线。示例: sed '1 c\' = > 将替换第1行中的文本。

在编写命令时,c\部分之后的任何内容都放入一个新行,并且应该包含新行文本。


最后,在一个名为 original_file.txt的文件中用文本‘ foo’“替换”第1行的示例。注意,我们将 sed 输出保存在一个临时文件中,然后将临时文件输出回原始文件:

# file contents
$ cat original_file.txt
bar


# the replace command
$ sed '1 c\
foo' original_file.txt > temp_file.txt
 

# output contents of temp_file and overwrite original
$ cat temp_file.txt > original_file.txt


# delete the temp file
$ rm -rf temp_file.txt

如果你想使用参数的 lineNumber 和替换行,然后 awk 不容易工作(对我来说)。我跑了1个小时,你可以看到下面:)

lineNumber=$(grep --line-number "u want to replace line any keyword" values.txt  | cut -f1 -d:)
replacedLine="replacing new Line "
# for sed prepare => if your replacedLine have '/' character (URL or something) u must use command bellow.
replacedLine=${replacedLine//\//\\\/}


sed -i $lineNumber's/.*/'"$replacedLine"'/'  values.txt