固定長ファイルがsedまたはawkに置き換えられました

固定長ファイルがsedまたはawkに置き換えられました

487バイトの固定長ファイルがあり、各レコード位置407-415(9バイト)は数値フィールドです。時には、フィールドに英数字の組み合わせが表示されることがあります(123ABC123、ABC000123...)。レコードにこのような内容が含まれている場合は、そのバイトで00000000を置き換えたいと思います。

答え1

そしてawkソリューション

awk 'BEGIN{FS=OFS=""}{f=0;for(i=407;i<=415;i++){if($i!~/0-9/){f=1}};if(f){for(i=407;i<=415;i++){$i=0}};print }' fixed

フィールド区切り文字を空にするように定義し、各文字はフィールドです。次に、各レコードのフラグをf0(数字と仮定)に設定します。文字 407-415 を /0-9/ と比較します。不一致がある場合、fを1に設定します。次にf = 1の場合、9文字をすべて0に置き換えてその行を印刷します。

答え2

他の答えは複雑に見えるので、ここに簡単なsed説明があります。

sed -E '/^.{406}[0-9]{9}/!s/(.{406}).{9}/\1000000000/'

拡張(options -E)正規表現は、406の任意の文字()で始まり、その後に9つの数字が^.{406}[0-9]{9}続く行(レコードが行であると仮定し、そうでなければ-zGNUにオプションを追加する)と一致するsedため、407から415まではすべて数値です。逆一致()の場合、最初の406文字は保持され(代替の最初の部分を表す)、次の9文字は0に置き換えられます。^.{406}!\1()

テキスト処理を要求する場合は、これはバイト処理ではなくテキスト処理であることに注意してください。マルチバイト文字は、2バイトではなく1文字としてカウントされます。

答え3

これは、入力ファイルがテキストであるかバイナリであるかに関係なく機能します。

printf %s "$(head -c 406 test_file | xxd -p)" "000000000000000000" "$(tail -c $((487-415)) test_file | xxd -p)" | tr -d '\n' | fold -32 | xxd -p -r -c 16 > test_file_final

またはこれ:

printf %s "$(head -c 406 test_file | xxd -p)" "$(head -c 9 /dev/zero | xxd -p)" "$(tail -c $((487-415)) test_file | xxd -p)" | tr -d '\n' | fold -32 | xxd -p -r -c 16 > test_file_final

以下を使用する必要はありません。$((487-415))...簡単に使用できます72。数字のソースをより明確にするためにこれを行います。

あなたがやっていることは、ファイルの最初の406バイトを取得してから9つのヌルバイトを取得することです(この9つのヌルバイトは、たとえば18個のゼロを持つ通常の文字列から生成できます)。[最初のオプション]または9つの生バイト/dev/ゼロ [2番目のオプション])次に、ファイルのバイト416から最後まで開始し、このツリーブロックを一緒に接続して目的の出力を作成します。


または次に交換したい場合文字0(いいえヌルバイト)以下を使用してください。

printf %s "$(head -c 406 test_file | xxd -p)" "303030303030303030" "$(tail -c $((487-415)) test_file | xxd -p)" | tr -d '\n' | fold -32 | xxd -p -r -c 16 > test_file_final

それにもかかわらず、上記のコマンドは次のように置き換えられます。条件はテストされません。 このバイトで16進文字をテストするには、nullバイトの代わりにこれを使用してください。:

シングルラインバージョン:

if ! [[ "$(tail -c $((487-406)) test_file | head -c 9)" =~ [[:xdigit:]]{9} ]]; then printf %s "$(head -c 406 test_file | xxd -p)" "000000000000000000" "$(tail -c $((487-415)) test_file | xxd -p)" | tr -d '\n' | fold -32 | xxd -p -r -c 16 > test_file_final; fi

スクリプトバージョン:

if ! [[ "$(tail -c $((487-406)) "$1" | head -c 9)" =~ [[:xdigit:]]{9} ]]
then
    printf %s "$(head -c 406 "$1" | xxd -p)" \
              "000000000000000000" \
              "$(tail -c $((487-415)) test_file | xxd -p)" \
              | tr -d '\n' \
              | fold -32 \
              | xxd -p -r -c 16 \
              > "${1}_with_replacement_done"
fi

またはゼロ文字に置き換えてください。:

シングルラインバージョン:

if ! [[ "$(tail -c $((487-406)) test_file | head -c 9)" =~ [[:xdigit:]]{9} ]]; then printf %s "$(head -c 406 test_file | xxd -p)" "303030303030303030" "$(tail -c $((487-415)) test_file | xxd -p)" | tr -d '\n' | fold -32 | xxd -p -r -c 16 > test_file_final; fi

スクリプトバージョン:

if ! [[ "$(tail -c $((487-406)) "$1" | head -c 9)" =~ [[:xdigit:]]{9} ]]
then
    printf %s "$(head -c 406 "$1" | xxd -p)" \
              "303030303030303030" \
              "$(tail -c $((487-415)) test_file | xxd -p)" \
              | tr -d '\n' \
              | fold -32 \
              | xxd -p -r -c 16 \
              > "${1}_with_replacement_done"
fi

関連情報