区切り文字なしでテキストファイルから列を抽出する

区切り文字なしでテキストファイルから列を抽出する

デフォルトでは、各行が一緒に圧縮されたデータストリームである大きなテキストファイルがあります。特定の列の一部のデータエラーを調査するように求められました。データはいかなる方法でも分離されません。ただし、「列」の長さのリストと各「列」に関連するデータがあるかどうかの説明があります。

Excelを使用しますが、Excelの列の区切り制限は1行に1000文字で、各行はそれ以上です。これらのフィールドの多くには、フィラーとして30個の空白文字列があり、少なくとも15個程度があります。指定された「空」フィールドを解析したいと思います。

私にとって必要なのは、ファイルを入力して提供できる配列を使用して、列の長さと「X」などの表示を使用して無視したい列を無視し、新しいファイルをエクスポートする方法です。区切り記号を使用すると、分析のためにExcelに戻すことができます。

たとえば、行を含むファイルがあり、aaaaaabbbbbccccdddddeeeffffffファイルに配列を提供すると、その行[6 5 4X 5 3X 6]を含むファイルが作成されます。aaaaaa^bbbbb^ddddd^ffffff

私が使用できる方法はありますかgrepawkそれともこれを行う方法はありますかsed

よろしくお願いします。

答え1

短いcutコマンドモード:

サンプルinput.txtコンテンツ:

aaaaaabbbbbccccdddddeeeffffff
wwwwwwddddd111133333xxxaaaaaa
ffffff00000sssszzzzz000rrrrrr

働く:

cut -c 1-6,7-11,16-20,24-29 --output-delimiter=^ input.txt
  • -c- 文字のみ選択

  • 1-6,7-11,16-20,24-29- 連続文字位置範囲、柔軟で調整可能

  • --output-delimiter=^- 出力フィールドの区切り記号を必要に応じて調整できます。


出力:

aaaaaa^bbbbb^ddddd^ffffff
wwwwww^ddddd^33333^aaaaaa
ffffff^00000^zzzzz^rrrrrr

答え2

GNU awkがある場合は、明示的なフィールド幅を指定できます。

$ printf 'aaaaaabbbbbccccdddddeeeffffff\n' | 
    gawk -v FIELDWIDTHS="6 5 4 5 3 6" -v OFS="^" '{print $1, $2, $4, $6}'
aaaaaa^bbbbb^ddddd^ffffff

バージョン4.2以降、構文を使用して文字をスキップできますn:m

printf 'aaaaaabbbbbccccdddddeeeffffff\n' |
   gawk -v FIELDWIDTHS="6 5 4:5 3:6" -v OFS="^" '{$1=$1} 1'
aaaaaa^bbbbb^ddddd^ffffff

(指定されたフィールド幅でのみ再評価を強制します$1=$。)$0

例を見るGNU Awkユーザーガイド:4.6固定幅データの読み取り

答え3

正確な入力と希望の出力を見ないと言うのは難しいですが...

sed -e "$(
  printf '%d\n' 6 5 4 5 3 6 |
    awk '
      {
        f[NR] = f[NR-1] + $1
      }
      END {
        for (i=NR; i>0; i--) {
          printf "s/./&^/%d\n", f[i]
        }
      }
    '
)" infile.txt | cut -d^ -f1,2,4,6

検証されていません。間違いはないだろうと約束します。 ;)


はい、テストしてみました。最後の支柱を逃したEND。他のエラーはありません。サンプル入力で完璧に動作します。出力は次のとおりです

aaaaaa^bbbbb^ddddd^ffffff

答え4

改良版ロマン・ペレクレストのcut答えX、スキップされた列数を示すサフィックスを含む列配列パーサーを含みます。

配列をロードし$n、配列を数値に解析する関数を作成しますcut -c

n=(6 5 4X 5 3X 6)
col_array() { j=$(h=0; 
                  for f in $@; do 
                      g=${f/[Xx]};
                      i=$((h+1));
                      h=$((h+g));
                      [ $g = $f ] && echo -n $i-$h,
                  done;) ; 
              echo ${j%,}; }

文書入力.txt含む:

aaaaaabbbbbccccdddddeeeffffff
wwwwwwddddd111133333xxxaaaaaa
ffffff00000sssszzzzz000rrrrrr

col_array()次のように使用しますcut

cut -c $(col_array  ${n[@]}) --output-delimiter=^ input.txt

出力:

aaaaaa^bbbbb^ddddd^ffffff
wwwwww^ddddd^33333^aaaaaa
ffffff^00000^zzzzz^rrrrrr

col_array()引数が解析されるため、配列は必ずしも必要ではありません。

cut -c $(col_array 3 5X 7) --output-delimiter=^ input.txt

出力:

aaa^bbbcccc
www^ddd1111
fff^000ssss

関連情報