AWK意外的substr()行为

AWK意外的substr()行为,awk,Awk,使用AWK,我想处理以下文本: J.Nawrocki & W.Complak 进入: 我有: { for(i=1;i<=NF;++i){ if ($i ~ /[A-Z]\.[A-Z][a-z]*/) { len=length($i); name=substr($i,1,2); surname=substr($i,3,len); printf("%s %s",surname,name); } else printf("%s",$i);

使用AWK,我想处理以下文本:

J.Nawrocki & W.Complak
进入:

我有:

{ for(i=1;i<=NF;++i){
if ($i ~ /[A-Z]\.[A-Z][a-z]*/)
    {
    len=length($i);
    name=substr($i,1,2);
    surname=substr($i,3,len);
    printf("%s %s",surname,name);
    }
else printf("%s",$i);
}
printf("\n");
}

(第一个标志是空格)。为什么“W.”会覆盖行的开头?

您可以尝试以下脚本:

{ 
    for(i=1;i<=NF;++i){
        if ($i ~ /[A-Z]\.[A-Z][a-z]*/)
        {
            len=length($i)
            name=substr($i,1,2)
            surname=substr($i,3)
            $i= surname" "name
        }
    }
    print 
}
{

对于(i=1;i您可以尝试以下脚本:

{ 
    for(i=1;i<=NF;++i){
        if ($i ~ /[A-Z]\.[A-Z][a-z]*/)
        {
            len=length($i)
            name=substr($i,1,2)
            surname=substr($i,3)
            $i= surname" "name
        }
    }
    print 
}
{

对于(i=1;i
awk-F'&'-vofs=“&”{for(i=1;i
awk-F'&'-vofs=“&”{for(i=1;i很高兴它变成了一个行结尾的东西(你原来的方法在mac上也很好用)。作为个人练习,我设计了一个sed方法,下面是,以防你发现它在其他上下文中有用

当前代码的逻辑没有考虑多个首字母、带有介词的名称(例如A.von Humboldt)等的可能性。因此,这里有一个具有相同约束的sed方法:

echo "J.Nawrocki & W.Complak" | sed -E 's/([A-Z]\.)([A-Z][a-z]*)/\2 \1/g'
取任意数量首字母的人:

echo "J.A.Nawrocki & W.Complak" | sed -E 's/(([A-Z]\.)+)([A-Z][a-z]*)/\3 \1/g'
还有一种姓氏可以有前置介词(带空格或不带空格):


很高兴它变成了一个行结束的东西(你的原作在mac上也很适合我)。作为一个个人练习,我设计了一个sed方法,如下所示,以防你发现它在其他环境中有用

当前代码的逻辑没有考虑多个首字母、带有介词的名称(例如A.von Humboldt)等的可能性。因此,这里有一个具有相同约束的sed方法:

echo "J.Nawrocki & W.Complak" | sed -E 's/([A-Z]\.)([A-Z][a-z]*)/\2 \1/g'
取任意数量首字母的人:

echo "J.A.Nawrocki & W.Complak" | sed -E 's/(([A-Z]\.)+)([A-Z][a-z]*)/\3 \1/g'
还有一种姓氏可以有前置介词(带空格或不带空格):

mawk'{sub(/J.Nawrocki&W.plampk/,“Nawrocki J.\&plampk W.”)1'文件
Nawrocki J.和Plumk W.

mawk'{sub(/J.Nawrocki和W.Plumk/,“Nawrocki J.\&Plumk W.”)1'文件

Nawrocki J.&;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp(@uluroki您使用的是什么文件格式?Unix还是dos?请注意,awk不能很好地处理dos行结尾(
\r\n
)。是的,我正在使用dos行结尾。我也尝试过使用awk“split()”,但它对我也不起作用。顺便说一句:我复制粘贴了您的代码并执行了,但失败了:/我仍然得到“W.rocki J.&Splack”:/@uluroki奇怪..它对我来说很好。你使用的是哪个版本的
awk
?我使用的是Gnu awk版本3.1.8。顺便说一下,你的原始代码也对我有效:)Gnu awk 4.0.1,Debian 7.2 64位。这没有任何意义:(@uluroki你使用的是什么文件格式?Unix还是dos?注意,awk不处理dos行结束(
\r\n
)非常好..是的,我正在使用dos行尾。我还尝试使用awk'split()'但这对我也不起作用。顺便说一句:我复制粘贴了你的代码并执行了,但失败了:/如果iput总是相同的话,这会起作用。但是可以有另一行有或多或少的随机词集,而没有'&'。如果iput总是相同的话,这会起作用。但是也可以有另一行有或多或少的随机词集,没有&。
echo "J.A.Nawrocki & W.Complak" | sed -E 's/(([A-Z]\.)+)([A-Z][a-z]*)/\3 \1/g'
echo "J.A.Nawrocki & W.von Complak" | sed -E 's/(([A-Z]\.)+)([a-z]*[[:space:]]?[A-Z][a-z]*)/\3 \1/g'