从命令行在文件的每一行开头添加字符串的最简单方法是什么?


8

我正在寻找一种在每行开头添加字符串的方法(每行相同的字符串)。不是可定制的东西,而是易于记住的东西,并且可以在每个POSIX兼容平台(以及每个shell)上使用。

Answers:


8

您可以使用sed

sed -i 's/^/your_string /' your_file

感谢Stephane和Marco的评论,请注意,该-i选项不是POSIX。POSIX的方法可以做到

sed 's/^/your_string /' your_file > tmp_copy && mv tmp_copy your_file

perl

perl -pi -e 's/^/your_string /' your_file

说明

这两个命令都执行正则表达式替换,用^所需的字符串替换行()的开头。这-i两个命令中的开关可确保在适当位置编辑文件(即,更改将反映在文件中,而不是打印到stdout)。

sed应该可以在任何符合POSIX的操作系统上使用,并且perl应该在大多数现代Unices上都可以使用,除了那些经过努力将其删除的软件。


1
较小的更正:-i开关未在适当位置编辑文件。它创建一个新文件,并在完成后覆盖原始文件(证明:inode发生了变化)。实际上没有很多工具可以进行就地编辑,这是很危险的操作。此外,由于您提到了POSIX,因此-i对于POSIX兼容而言,此开关不是必需的sed,这是某些特定实现的功能。
Marco Marco

2
sed -i不是POSIX。是GNU。FreeBSD sed也有类似的选项,但是您需要sed -i ''那里。
斯特凡Chazelas

@Marco我知道会-i创建一个临时副本(这就是为什么我说所做的更改会反映在原始文件中的原因);我的意思是,您获得与就地替换相同的语义。请检查更新后的答案是否符合POSIX。
Joseph R.

严格来说,更改将反映在与原始文件同名的新文件中。
基思·汤普森

1
我经常使用$$(当前shell的进程ID)作为临时文件名的一部分。这样就避免了每次都在考虑保证唯一名称的command filename > filename.$$ && mv filename.$$ filename
Keith Thompson

14
:|paste -d'foo ' - - - - input > output

(开个玩笑,尽管您可能会发现它是此处发布的所有解决方案中最快的:-b)。

规范的方式是:

sed 's/^/foo /' < input > output

但是,它不容易适应任意字符串。例如,

sed "s/^/$var /"

只有工作,如果$var不包含,&\/也不是换行符。

在这方面,

export var
awk '{print ENVIRON["var"], $0}'

要么

perl -pe '$_="$ENV{var} $_"'

会更好。


:P
Rahul Patil

4

我使用awk前缀字符串“ foo” 提出了一种解决方案。

awk '{ print "foo", $0; }' input > output

awk是跨平台的,可在任何POSIX系统上使用。它不执行就地编辑。如果要编辑文件而不创建第二个文件,则必须使用一个临时文件。请参阅约瑟夫的sed答案,它显示了语法。另一个技巧是使用以下语法,该语法基本上是使用与原始文件相同的文件名创建一个临时文件。

{ rm file; awk '{ print "foo", $0 }' > file; } < file

reducto# wc -l foo`914 foo` reducto# { rm foo ; awk '{ print "prepend" , $0 }' > foo } < foo >这似乎不起作用。我正在尝试,因为重定向到原始版本使我感到紧张,但它甚至没有开始。
kurtm

1
如果此示例在外部使用括号而不是大括号,则将起作用。
kurtm

4

通过使用通常进行就地编辑的工具-编辑器,可以避免使用流工具进行就地编辑的问题!

ex sample.txt -c "%s/^/foo /" -c wq

另一个好处是,对于精通一个真正的编辑器的任何人来说,这些命令都很容易理解。


2

您可以使用perl以下方法:

$ perl -pi -e 's/^/mystring /' afile.txt

创建一个示例文件。

$ seq 5 > afile.txt

$ cat afile.txt
1
2
3
4
5

运行上面的命令:

$ perl -pi -e 's/^/mystring /' afile.txt

$ cat afile.txt
mystring 1
mystring 2
mystring 3
mystring 4
mystring 5

如今,Perl似乎很普遍,但很长一段时间以来,它并不是普遍的。我敢打赌,那里有一些罕见的UNIX变种,它们坚决拒绝将perl作为基础。有一点要注意。
kurtm

@kurtm在这里查看讨论。显然,AIX默认没有Perl,嵌入式系统也没有。
terdon

2
@DavidSainty-足够通用。Q被标记为Bash,所以我很难想象拥有Bash但没有Perl的系统。无论如何,这是5个答案之一,其他几个显示了如何使用sed,我显示了如何使用Perl ....
slm

1
@DavidSainty显然只有OpenBSD。我猜我是做这个假设的,因为公开赛的人往往对他们在基地的表现持保守态度。OpenBSD确实在基础中提供了它。
kurtm

1
@slm:“ 我很难想象拥有Bash但没有Perl的系统 ”。我的桌子上坐着几个这样的系统。(它们恰好是嵌入式系统。)
Keith Thompson

1

只需使用Bash

 while IFS= read -r line; do echo "foo" "${line}" ; done  < input > Output

使用Python

python -c "import sys; print 'foo '.join([ l for l in sys.stdin.readlines() ])" < input > Output

如果要就地编辑

import fileinput
import sys

for line in fileinput.input(['inputfile'], inplace=True):
    sys.stdout.write('foo {l}'.format(l=line))

参考链接


为什么它的工作速度比awk快?
拉胡尔·帕蒂尔

1
它的工作速度仅比awk很小的文件要快。行为在回显实现中会有所不同,并且会去除前导和尾随空格,并专门处理反斜杠。
斯特凡Chazelas

@StephaneChazelas是的。您是刚刚通过测试的100%正确... paste.ubuntu.com/6210934
拉胡尔·帕蒂尔

prefix () { while IFS= read -r REPLY; do printf "%s%s\n" "$1" "$REPLY"; done; }应该更正确。
马特

1
为什么{}呢?我认为@Matt建议您将其制成命名函数,{}没有函数名又有什么意义呢?
terdon

-1

或者,您可以执行以下操作:

vi filename.txt

Esc(以确保您处于NORMAL模式下),然后输入以下命令:

:1,$ s/^/mystring

请注意,由于用户询问的是文件的每一行,因此可以替换1,$ 为simple %。这使命令:%s/^/string/
HalosGhost 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.