我经常发现自己试图对相当大的文件进行简单的文本操作。似乎应该有一种方法可以使用各种 Unix 文本修改工具中的一个或其他来编写脚本,但我不知道具体是如何实现的。
作为一个具体的例子,假设我有一些如下所示的源代码:
foo1 = undefined
foo2 = undefined
foo3 = foobar 7
foo4 = undefined
我想把它改成这样:
foo1 = error "foo1"
foo2 = error "foo2"
foo3 = foobar 7
foo4 = error "foo4"
它好像地狱里应该有某种方法可以自动完成这种转变。显然我可以轻松地写一个程序在真正的编程语言中。但肯定有一些命令行工具可以做到这一点。 (?)
作为一个更复杂的例子,我该如何转向
foo=ABC
bar=DEF
baz=GHI
foo=123
bar=456
baz=789
进入
Magic(ABC, DEF, GHI);
Magic(123, 456, 789);
更一般地说,我应该使用哪种工具来进行此类转换?那是sed
、还是awk
、或者……?
答案1
这取决于具体情况。您的第一个示例可以使用 或 来sed
解决awk
。例如,使用awk
:
$ awk '
/undefined/ {printf "%s = error \"%s\"\n", $1, $1; next}
{print}
' input
其产生:
foo1 = error "foo1"
foo2 = error "foo2"
foo3 = foobar 7
foo4 = error "foo4"
或者使用sed
:
sed '
/undefined/ s/\([^ ]*\) =.*/\1 = error "\1"/
' input
您的第二个示例可能更容易使用awk
或一些高级语言(如 Perl 或 Python)来完成。再次,与awk
:
awk '
{
split($0, parts, "=")
items[i++] = parts[2]
}
i%3 == 0 {
printf "Magic(%s, %s, %s)\n", items[0], items[1], items[2]
i=0
}
' input
其产生:
Magic(ABC, DEF, GHI)
Magic(123, 456, 789)
更一般地说......我不确定是否可以提供一般性答案。这实际上取决于您想要完成的具体任务。一旦你退出,awk
你就已经写一个程序在一个真正的编程语言,因此您不应该仅仅因为更高级的工具(如 Perl 或 Python 或 Ruby 或其他)功能更强大而回避它。
答案2
sed
非常适合简单的文本操作 - 通常是单行编辑,尽管它可以处理多行(需要付出很大的努力)。总体而言sed
,由于缺乏变量和算术计算,它相当受限制,但尽管如此,它在许多情况下确实提供了最简单的解决方案。
awk
对于简单和复杂的文本操作和数字计算都非常有效,但它并不适合除此之外的事情。
对于第一个例子:
sed -E 's/^([^ ]+) = undefined$/\1 = error "\1"/' file1
awk '$3=="undefined"{ $3="error \"" $1 "\"" } {print $0}' file1
对于第二个例子,基于 =价值观要么全大写字母,要么全数字。它还对所有非 Magic 行进行分组(要删除,只需删除out[0]
语句):
awk -F'=' 'BEGIN{ # split regular expressions, using `x7F` as delimiter (or any char not in the regex)
n=split("^[A-Z]+$" "\x7F" "^[0-9]+$",rx,"\x7F")
}
{ for( i=1;i<=n;i++ ){
if( $2 ~ rx[i] ){
out[i]=out[i] sprintf( (out[i] ?", " :"") "%s", $2)
break
} }
if( i>n ) out[0]=out[0] $0 RS # non-matching lines
}
END{ printf out[0]
for( i=1;i<=n;i++ ){ print "Magic(" out[i] ")" }
}' file2
答案3
我会使用 Perl,因为它是一种(相当“正常”)编程语言,围绕强大的文本操作(搜索、用正则表达式以 vi(1) 样式替换)构建。但很多人会认为我是异端,并使用 Python。两者都随任何 Linux 发行版一起分发,并且都有不错的 Windows 实现(我确信 Mac 也是如此)。 Python 的优点是它可以用来为 Fedora 等管理工具构建大部分 GUI,因此应该已经安装它。
awk(1)
都是sed(1)
强大的工具,但有些专一......