スペースを別の値に置き換える方法は?

スペースを別の値に置き換える方法は?

約8,000のレコードを含む区切りファイルがあります|

3列が空の場合は2列の値に変更したいと思います。私たちはこれをどのように達成しますか?

入力する:

1|100437251|
2|51414204|
3|111651604|111651604
4|8321737|8321737
5|27263401|27263401

出力:

1|100437251|100437251
2|51414204|51414204 
3|111651604|111651604
4|8321737|8321737
5|27263401|27263401

sed交換コマンドを試してみましたsed -i "s/ /$2/g" input > output

答え1

そして:

sed -E 's/^([^|]*\|)([^|]*)\|$/\1\2|\2/' infile

この部分は、([^|]*\|)最初の列と区切り文字(\1逆参照)をキャプチャします。
この部分は([^|]*)2番目の列(\2逆参照)をキャプチャします。
この部分は\|$行末の最後の区切り文字をキャプチャし、その後に他の区切り文字はありません(3番目の列が空であることを意味します)。

このセクションでは、\1\2|\2逆参照アドレスを使用して最初と2番目の列を返し、区切り文字を使用して2番目の列を再コピーします。


3番目の列が空ではなく、タブ/スペース([[:space:]])などの空白文字が含まれる可能性がある場合は、代わりにこの列を使用してください。

sed -E 's/^([^|]*\|)([^|]*)\|[[:space:]]*$/\1\2|\2/' infile

そして:

awk 'BEGIN{ FS=OFS="|" } $3 ~/^[[:space:]]*$/ { $3=$2 }1' infile

FSはF生産するS区切り記号、OFSの例酸素出力F生産するS次に、3番目の列が空であるか/タブ/スペースであることを確認し、その内容を2番目の列と同じように更新します。次に印刷します1

答え2

を使用しawk、3番目のフィールドにスペース以外の文字が含まれていない限り、3番目のフィールドを2番目のフィールドに置き換えます。

$ awk -F '|' 'BEGIN { OFS = FS } $3 !~ /[^[:blank:]]/ { $3 = $2 }; 1' file
1|100437251|100437251
2|51414204|51414204
3|111651604|111651604
4|8321737|8321737
5|27263401|27263401

sed3番目のフィールドが空白または空白のみを含む場合は、2番目のフィールドの番号を挿入するために使用されます。

$ sed 's/\([[:digit:]]\{1,\}\)|[[:blank:]]*$/\1|\1/' file
1|100437251|100437251
2|51414204|51414204
3|111651604|111651604
4|8321737|8321737
5|27263401|27263401

3番目のフィールドは次のとおりです。いつも2番目のフィールドと同様に、3番目のフィールドのすべてのテストを無視し、2番目のフィールドの値になるように強制することもできます。

まず、次を使用しますawk

$ awk -F '|' 'BEGIN { OFS = FS } { $3 = $2 }; 1' file
1|100437251|100437251
2|51414204|51414204
3|111651604|111651604
4|8321737|8321737
5|27263401|27263401

でも

$ awk -F '|' 'BEGIN { OFS = FS } { print NR, $2, $2 }' file
1|100437251|100437251
2|51414204|51414204
3|111651604|111651604
4|8321737|8321737
5|27263401|27263401

これにより、最初の列も再生成されます。

次に、次を使用しますsed

$ sed 's/|[^|]*$//; s/[[:digit:]]\{1,\}$/&|&/' file
1|100437251|100437251
2|51414204|51414204
3|111651604|111651604
4|8321737|8321737
5|27263401|27263401

このsedコマンドは最初に最後のフィールドを削除してから、削除されたフィールドより前のフィールドから再生成します。

または、次のようなもの

$ cut -d '|' -f 2 file | sed '=; s/.*/&|&/' | sed 'N; y/\n/|/'
1|100437251|100437251
2|51414204|51414204
3|111651604|111651604
4|8321737|8321737
5|27263401|27263401

2番目のフィールドを使用してデータを抽出し、列挙に使用してフィールドの重複をcut関連付け=て作成sedし、最後に正しい区切り文字を使用してデータに行番号を追加します。

(プロセスの代替を使用)の組み合わせを使用して、シェルでcutこれを行うこともできます。pastebash

$ paste -d '|' <( cut -d '|' -f 1,2 file ) <( cut -d '|' -f 2 file )
1|100437251|100437251
2|51414204|51414204
3|111651604|111651604
4|8321737|8321737
5|27263401|27263401

答え3

そしてawk

awk -F'|' -v OFS='|' '{if($3=="")$3=$2}1'

sed2番目の列が常に数値の場合の簡単な例です。

sed -E "s/([0-9]*)\|$/\1|\1/"

答え4

、を使って空であるかどうかをawk確認してください$3

awk -F'|' -v OFS='|' '$3 == "" {$3=$2} 1' file
1|100437251|100437251
2|51414204|51414204
3|111651604|111651604
4|8321737|8321737
5|27263401|27263401
  • または
awk -F'|' -v OFS='|' 'length($3) == 0 {$3=$2} 1' file

関連情報