awk perl 新しい行の最初の列をコピー

awk perl 新しい行の最初の列をコピー

私はbashを使用し、次のテーブルがあります

001_1_174    [g/n                         474536         482492          
mo[g/n                    482492         504062          
'er/                      504062         517352          
ruze                      517352         529562                  
001_1_400    uz[`f                         960192        966656           
.ire                      966656         984416           
tuf/[                     984416         1006166

最初の行(数字と下線のみを含む)の文字列を別の数字まで別の行にコピーし、次の数字に対してこれを行いたいと思います。

このように

001_1_174    [g/n                    474536         482492           
001_1_174  mo[g/n                    482492         504062           
001_1_174  'er/                      504062         517352           
001_1_174  ruze                      517352       529562                  
001_1_400    uz[`f                   960192        966656           
001_1_400   .ire                      966656         984416           
001_1_400   tuf/[                     984416         1006166

答え1

シングルライナーを好む場合は、Perlを使用してください。

$ perl -pe 'if (/^\s*([\d_]+)/) {$x=$1} else {$_="$x $_"}' input.txt

それ以外の場合は、スクリプトで次の操作を行います。

use warnings;
use strict;

my $prefix;
while (<>) {
    if ( /^\s*([\d_]+)/ )
        { $prefix = $1 }
    else { $_ = "$prefix $_" }
    print;
}

両方出力:

001_1_174    [g/n                         474536         482492          
001_1_174 mo[g/n                    482492         504062          
001_1_174 'er/                      504062         517352          
001_1_174 ruze                      517352         529562                  
001_1_400    uz[`f                         960192        966656           
001_1_400 .ire                      966656         984416           
001_1_400 tuf/[                     984416         1006166

正規表現は「数字と下線のみ」仕様に基づいており、行の先頭にスペースを入れることができます(\s*望ましくない場合は削除)。さらに、これはいいえ読んだ最初の行が数字で始まらない場合は正常に動作します!

答え2

$ awk 'NF == 4 { col1 = $1; print; next } { print col1, $0 }' file
001_1_174    [g/n                         474536         482492
001_1_174 mo[g/n                    482492         504062
001_1_174 'er/                      504062         517352
001_1_174 ruze                      517352         529562
001_1_400    uz[`f                         960192        966656
001_1_400 .ire                      966656         984416
001_1_400 tuf/[                     984416         1006166

まず、入力行に4つの列があることを確認してください。存在する場合、col1変数は最初の列の値に設定され、行はそのまま印刷され、スクリプトは次の行から続行されます。それ以外の場合は行が印刷されますが、値は元のcol1最初の列の前に挿入されます。

これは、ランダムに見える横説説に空白文字が含まれていない場合にのみ機能します。その場合は、列間に使用される区切り記号(タブなど)-F 'delimiter'を使用する必要があります。delimiter'\t'

また、最初の行に4つの列があるとします。それ以外の場合、col1その行の変数は設定されていません。


実装するコメントの提案~からユーザーカスこれは入力データの列数とは無関係です(最初の行に特別な最初の列を含むすべての行の正しい列数が含まれていると仮定します)。

$ awk 'NR == 1 { cols = NF } NF == cols { col1 = $1; print; next } { print col1, $0 }' file
001_1_174    [g/n                         474536         482492
001_1_174 mo[g/n                    482492         504062
001_1_174 'er/                      504062         517352
001_1_174 ruze                      517352         529562
001_1_400    uz[`f                         960192        966656
001_1_400 .ire                      966656         984416
001_1_400 tuf/[                     984416         1006166

答え3

最短awk:

awk 'NF < 4{ $0=n OFS $0 }{ n=$1 }1' file

出力:

001_1_174    [g/n                         474536         482492          
001_1_174 mo[g/n                    482492         504062          
001_1_174 'er/                      504062         517352          
001_1_174 ruze                      517352         529562                  
001_1_400    uz[`f                         960192        966656           
001_1_400 .ire                      966656         984416           
001_1_400 tuf/[                     984416         1006166

特定のフィールド形式を使用するには、次を使用して上記の内容を変更できます。

awk 'NF<4{ $0=n OFS $0 }$1~/^[0-9_]+$/{ n=$1 }1' file

関連情報