Linux中的条件字符串替换

时间:2016-06-02 12:27:00

标签: shell unix text sed command

我有一个庞大的(100M行)文件,我需要在linux上编辑才能上传到我们的数据库。它是一个以管道分隔的文件,目前采用以下格式:

a|b|c|d
e|f|g|h
  ijkl
  mn
o|p|q|r
s|t|u|v

我想将其更改为以下格式:

a|b|c|d
e|f|g|h  ijkl  mn
o|p|q|r
s|t|u|v

我一直在尝试使用Regex和grep / sed / tr,但我是shell的新手并且非常困难。

有没有人有任何建议?这真的是一个很大的帮助,谢谢。

2 个答案:

答案 0 :(得分:0)

这个awk单行程适用于给定的例子:

kent$  cat f
a|b|c|d
e|f|g|h
  ijkl
  mn
o|p|q|r
s|t|u|v

kent$  awk -F'|' '{printf "%s%s", (NF==4&&NR>1?RS:""),$0}END{print ""}' f
a|b|c|d
e|f|g|h  ijkl  mn
o|p|q|r
s|t|u|v

如果我们测试:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $factory = $builder->getFormFactory();
    $domainsNamesTransformer = new DomainsNamesTransformer();

    $builder->add(
        $builder->create('domains', TextareaType::class, [
            'label' => 'form.names',
            'translation_domain' => 'global',
            'constraints' => [
                new Assert\NotBlank(),
            ],
        ])
        ->addModelTransformer($domainsNamesTransformer)
    );

    // Limit to user servers
    $builder->add('server', EntityServerType::class, [
        'user' => $options['user'],
        'nadmin_compliant' => true,
        'ip_network' => IpV4::NETWORK_PUBLIC,
        'required' => true,
        'constraints' => [
            new Assert\NotBlank(),
        ],
    ]);

    // Ask if user want a database
    $askDatabase = function (FormInterface $form, $server) {
        if ($server != null && $server->getMysqlServer === true) {
            $form->add('database', CheckboxType::class, [
                'label' => 'domain.form.associated_databases',
                'translation_domain' => 'front',
                'required' => false,
            ]);
        }
    };
}

答案 1 :(得分:0)

如果当前行的字段少于预期的字段数,则必须附加到上一行行:

a|b|c|d
e|f|g|h  ijkl  mn
o|p|q|r
s|t|u|v
tac file |
 awk -F'|' -v n=4 'NF != n {s = $0 " " s; next} {print $0, s; s = ""}' |
 tac

另一种看待它的方法是反转文件并记住没有正确数量字段的内容:

{{1}}