![Unix 中逐行修改](https://linux22.com/image/112016/Unix%20%E4%B8%AD%E9%80%90%E8%A1%8C%E4%BF%AE%E6%94%B9.png)
我正在寻找一种方法,在 UNIX 中对每一行使用管道分隔文件执行以下操作,但不确定从哪里开始:
- 查找一行文本中的字符(假设使用 GREP?)
- 如果找到,则在该行末尾添加一些文本(使用 SED?)
- 如果没有找到,则在同一行中查找另一个字符
- 如果发现在行尾添加文本,否则不执行任何操作
- 循环文件中的所有行
任何指示将不胜感激。
答案1
这就是全部sed
工作,您不需要额外的工具:
假设您想foo
在包含 an 的行末尾添加f
,并在不带,但带有 a 的bar
行末尾添加f
b
sed '/f/{
s/$/foo/
b
}
/b/s/$/bar/'
您可以使用 来“寻址”行/pattern/
,因此以下命令仅在包含该模式时才会执行。因此,在示例中,只有包含触发替换和命令组f
执行的行,因此仅当地址匹配时才应用内部的所有内容。分支到脚本末尾以避免为匹配。s
b
{}
b
b
没有分支的不同方法:
sed '/f/s/$/foo/;s/^[^f]*b[^f]*$/&bar/'
作为练习,您可以通过一些知识自己解决这个问题sed
,并在必要时使用man sed
。
答案2
如果您想在两种情况的行尾添加相同的文本字符串(要查找的字符:'X''Y'),那么您可以按如下方式执行:
sed -e 's/[XY].*/&__ADDEDTEXT__/' yourfile
另一方面,如果您希望根据字符将单独的文本放置在行尾,那么您可以这样做:
sed -e '
/X/s/$/__TEXT1__/; t
/Y/s/$/__TEXT2__/
' yourfile
我们使用t
(read as test) 命令来检测前一个s///
命令是否成功并跳转到当前行的 sed 代码末尾。另请注意语法:/regex/s/// => 如果一行包含正则表达式,则对该行执行替换。
答案3
Perl 也是一个有用的工具,可以轻松地一次完成所有事情。
因此,以 @Philippos 为例,perl 程序将如下所示(某些语法是可选的,添加是为了澄清):
perl -pe '(m/f/&&s/$/foo/)||(m/b/&&s/$/bar/)' file
这将读取file
并输出结果。您还可以使用-pi -e
代替-pe
(-i
意思是“就地”)来“编辑”文件,因此:
perl -pi -e '(m/f/&&s/$/foo/)||(m/b/&&s/$/bar/)' file
可能还有一种方法可以做到这一点,awk
尽管最初的测试失败了(我对 AWK 不太精通),用 Ruby(看起来几乎一样,如果你想要例子,请告诉我),并且在纯 Bash 中它可以很有趣。