awkを使用して1行を複数のスペースの代わりに単一のスペースに分割する

awkを使用して1行を複数のスペースの代わりに単一のスペースに分割する

私が制御できない型の行を分割しようとしています。パラメータ7と8が欠落している場合は空白に置き換えられる可能性があるため、最終的には次のようになります。

field1 field2 field3 field4 field5 field6   field9

現時点では、フィールド9はフィールド7として読み取られます。多くの検索では、次のことがうまくいくはずですが、そうではありません。これは私の部分の小さな文法エラーかもしれませんが、それを見つけることができないようです。

word1=`echo $LINE | awk 'BEGIN { FS="[ ]" } ; { print $9 }'`

答え1

LINEパラメータは引用符で囲まれていないため、inwordsplitting拡張が発生し、入力が受信されるまで7(シェルに示すように)になり、すべて空白で区切られます。 awkがこれを処理する前に行の空白が破損しないように、echoを出力として提供したいと思います(再びシェルで見ることができます)。これが参照パラメータによって防止されることです。$LINEecho $LINEawkwordsword

# How you want it to be given to awk:
$ printf '<%s> ' "$LINE"; echo
<field1 field2 field3 field4 field5 field6   field9> 
# Your attempt:
$ printf '<%s> ' $LINE; echo
<field1> <field2> <field3> <field4> <field5> <field6> <field9> 

フィールド6と9の間の余分なスペースがどのように消えるかを確認してください。

常に拡張子を引用する必要があります。拡張子を引用しないと、引用よりも問題が発生する可能性が高くなります。

答え2

可変入力長を処理するときにawkで非常に便利なパラメータは、フィールド数であるNFです。

lastword=`echo $LINE | awk '{ print $NF }'`

欠落している列に関係なく、常に最後の列を印刷します。途中で一部のフィールドが欠落している場合は、最後のフィールドで逆に計算することもうまく機能します。

例のように、空白で埋められた欠落/空の列を含むサンプルファイルは次のとおりです。

line1 field1 field2 field3 field4 field5 field6 field7 field8 field9
line2 field1 field2 field3 field4 field5 field6  field8 field9
line3 field1 field2 field3 field4 field5   field8 field9

そして

awk '{print $1 " " $2 " " $(NF-1) " " $NF}' file

    line1 field1 field8 field9
    line2 field1 field8 field9
    line3 field1 field8 field9

答え3

これを行うことができるはずですksh93

set -f
IFS='  ' # two spaces
set -- $LINE
printf '%s\n' "$9"

空白を2倍にすると、図に示すように、一連の空白が1つとして処理され、先行および末尾の空白が無視される特別な動作が削除されますzsh

答え4

私の場合は、まずパイプを接続することにしましたtr。入力に現れる可能性のない文字(この場合はベルコード\a)にスペースをマップするだけです。

❯ echo 'a b  d' | tr ' ' '\a' | awk -F'\a' '{print "1="$1, "2="$2, "3="$3, "4="$4}'
1=a 2=b 3= 4=d

3番目のフィールド$3は空です。


1時間後にまた会いましょう。

関連情報