Unixコマンドラインで「test10」列を5文字に切り捨てるにはどうすればよいですか?
したがって、
test1,test2,test3,test4,test10,test11,test12,test17
rh,mbn,ccc,khj,ee3 eeeeeEeee ee$eeee e.eeeee2eeeee5eeeeeeee,a2,3,u
hyt,bb,mb,khj,R ee3ee eeEeee ee$eeee e.eeeee2eeeee5eeeeeeee,a,5,r
mbn,htr,ccc,fdf,F1ee eeeeEeee ee$eeee e.eeeee2eeeee5eeeeeeee,a,e,r
これに関して
test1,test2,test3,test4,test10,test11,test12,test17
rh,mbn,ccc,khj,ee3 e,a2,3,u
hyt,bb,mb,khj,R ee3,a,5,r
mbn,htr,ccc,fdf,F1ee ,a,e,r
答え1
ファイルが例と同じくらい簡単な場合は、次のいずれかを実行できます。
awk
$ awk -F, -vOFS=, 'NR>1{$5=substr($5,1,5)}1' file test1,test2,test3,test4,test10,test11,test12,test17 rh,mbn,ccc,khj,ee3 e,a2,3,u hyt,bb,mb,khj,R ee3,a,5,r mbn,htr,ccc,fdf,F1ee ,a,e,r
説明する
-F,
入力フィールド区切り記号をに設定し、,
変数-vOFS=,
(OFS
出力フィールド区切り記号)をに設定します,
。NR
は現在行番号なので、上記のスクリプトは5番目のフィールドを5文字のサブストリングに変更します。唯一のことは、1
「この行を印刷してください」のawkの略語です。perl
$ perl -F, -lane '$F[4]=~s/(.{5}).*/$1/ if $.>1; print join ",", @F' file test1,test2,test3,test4,test10,test11,test12,test17 rh,mbn,ccc,khj,ee3 e,a2,3,u hyt,bb,mb,khj,R ee3,a,5,r mbn,htr,ccc,fdf,F1ee ,a,e,r
説明する
Perlをawkのように振る舞い、
-a
与えられた文字に基づいて入力行を分割して-F
配列の要素として保存します@F
。次に、5番目のフィールドから最初の5文字を除くすべての文字を削除し(最初から計算され)、コンマで連結された結果の配列を0
印刷します。@F
sed
$ sed -E '1!s/(([^,]+,){4}[^,]{5,5})[^,]*,/\1,/' file test1,test2,test3,test4,test10,test11,test12,test17 rh,mbn,ccc,khj,ee3 e,a2,3,u hyt,bb,mb,khj,R ee3,a,5,r mbn,htr,ccc,fdf,F1ee ,a,e,r
説明する
これは代替演算子であり、一般的な形式はです
s/original.replacement/
。これは1!
、「最初の行ではこれを実行しないでください」を意味します。正規表現は、文字以外の文字セット,
と一致し、,
4 番 (([^,]+,){4}
)、,
非 5 文字 ([^,]{5}
) (5 番目のフィールドの最初の 5 つ)、フィールドの最後までのその他の文字 ([^,]+,
) と一致します。これらはすべて行の最初の部分に置き換えられ、フィールドを効果的に切り捨てます。
答え2
使用awk
:
awk -F , 'BEGIN { OFS = FS } NR > 1 { $5 = substr($5,1,5) }; 1' data.csv
この-F
フラグは入力フィールド区切り文字を設定し、このBEGIN
ブロックは出力フィールド区切り文字を入力フィールド区切り記号(カンマ)に設定します。
現在のレコードのシーケンス番号(NR
)が1より大きい場合(つまり、ヘッダー行を渡した場合)、関数は5番目のsubstr()
フィールド(列)を最大5文字に切り捨てます。これにより、入力データの最初の行が変更されるのを防ぎます。
単独で(おそらく)変更されたレコード(行)が標準出力として印刷されます1
。awk