![bash:在文件中的指定位置插入字符](https://linux22.com/image/4425/bash%EF%BC%9A%E5%9C%A8%E6%96%87%E4%BB%B6%E4%B8%AD%E7%9A%84%E6%8C%87%E5%AE%9A%E4%BD%8D%E7%BD%AE%E6%8F%92%E5%85%A5%E5%AD%97%E7%AC%A6.png)
假设我有以下文件
word1 something blabla
anotherword somethingelse asdf
yetanother else 123
对于每一行,我需要在第二列前面添加注释,该注释始终从位置 15 开始(即#
在位置 15 处插入)。我该怎么做?
答案1
假设其选项sed
为 GNU 或兼容的¶-r
sed -r -e 's/^.{15}/&#/' file
结果是
word1 #something blabla
anotherword #somethingelse asdf
yetanother #else 123
1 这是为了扩展正则表达式支持。现在大多数其他sed
人都支持-E
这一点(包括从 4.2 版开始的 GNU,sed
尽管直到 4.3 才被记录,在这个答案最初编写很久之后发布),因为这就是 2023 版 POSIX 标准中现在的内容。如果没有-E
/ -r
,您将\{...\}
使用{...}
.
答案2
另一个解决方案awk
:
awk '{$2="#"$2;print $0}' your_file
这将添加#
到第二个(空格分隔)列的开头,无论它出现在哪个位置。
答案3
要使用固定宽度字段,perl
's pack
/unpack
函数会很方便:
$ cat file
word 1 something blabla
anotherword somethingelse123asdf
yetanother else 123
$ perl -lne 'BEGIN {$format = "A15A16A*"}
@f = unpack$format;
$f[1] = "X$f[1]";
print pack $format, @f' file
word 1 Xsomething blabla
anotherword Xsomethingelse12asdf
yetanother Xelse 123
X
我们在第二个字段的开头插入。第二个字段仍然是 16 字节宽,在第二行的情况下意味着它被截断了。
答案4
awk 的答案awk '{$2="#"$2;print $0}'
是不正确的,因为它会重新格式化空白,并且当其中一列具有空白字符时会失败。
word1 something blabla
anotherword somethingelse asdf
yet another else 123
例如将变成:
word1 #something blabla
anotherword #somethingelse asdf
yet #another else 123
正确的 awk 答案是:
awk '{print substr($0,1,15) "#" substr($0,16) }'
给出输出:
word1 #something blabla
anotherword #somethingelse asdf
yet another #else 123