2番目の列を指定された長さに切り捨てる方法


9

フォームの指定された入力

XY981743    foobarlkasdf saflkas asfZR!sgfad asdSAD asdsadf SAdfasdf46lk lksad bar foolkasjfdrte

2番目の列のみを切り捨てるにはどうすればよいですか?区切り文字はTABで、2番目の列は最大75文字である必要があります。


もう少し一般的:awk 'BEGIN{OFS=FS="\t"} {$2=substr($2,1,75)}1' file
fedorqui

切り捨て(75番目以降の文字を削除)または折りたたみ(別の行に印刷)しますか?また、スペースは75文字にカウントされますか?
terdon

回答:


7

2番目の列の最初の75文字(スペースを含み、ファイル内の列が2つだけであると想定)だけを印刷する場合は、次のようにします。

$ perl -pe 's/(\t.{75}).*/$1/' file
XY981743    foobarlkasdf saflkas asfZR!sgfad asdSAD asdsadf SAdfasdf46lk lksad bar fool

または、GNUの場合sed

$ sed 's/\(.*\t.\{75\}\).*/\1/' file
XY981743    foobarlkasdf saflkas asfZR!sgfad asdSAD asdsadf SAdfasdf46lk lksad bar fool

または:

$ sed -r 's/(.*\t.{75}).*/\1/' file
XY981743    foobarlkasdf saflkas asfZR!sgfad asdSAD asdsadf SAdfasdf46lk lksad bar fool

または、を使用foldして、最初の91文字(識別子は8文字、タブは8文字)でカットするように指示し、最初の行のみを印刷することもできます。

$ fold -w 91 file | head -n1
XY981743    foobarlkasdf saflkas asfZR!sgfad asdSAD asdsadf SAdfasdf46lk lksad bar fool

ファイルに2列を超える列を含めることができ、2番目の列のみを切り捨てたい場合は、これを行うことができます(これは、先ほど気付いたように、Stephenの答えの言い換えにすぎません)。

$ awk -F"\t" -vOFS="\t" '{$2=substr($2,1,75)}1;' file
XY981743    foobarlkasdf saflkas asfZR!sgfad asdSAD asdsadf SAdfasdf46lk lksad bar fool

または(2番目の列の最初の75文字が正規表現として解釈できる場合、これは壊れることに注意してください):

$ perl -F"\t" -pale 's/$F[1]/substr($F[1],0,75)/e' file
XY981743    foobarlkasdf saflkas asfZR!sgfad asdSAD asdsadf SAdfasdf46lk lksad bar fool

それらは、2番目の列以外の列を切り捨てることがあります。最初のsedコマンドもGNUism(\t)を使用しています。
ステファンChazelas

@StéphaneChazelas なに\tGNUismは何ですか?マジ?タブを記述するポータブルな方法は何ですか?
terdon

1
私の答えを参照してください。LHSで移植可能に認識されている唯一のエスケープシーケンスは、RHSでは\nなく([...]多くの実装では内部にありません)です。
ステファンChazelas

@StéphaneChazelasいまいましい、ありがとう。複数の列を処理できるソリューションも追加しました。
terdon

あなたの最後のperlものはほとんど意味がありません。以下のような入力のインスタンスのために考えてaba\t.*
ステファンChazelas

10

を使用してawk、タブを使用してファイルを分割し、最初のフィールドを完全に出力し、2番目のフィールドの最初の75文字(最大で)を出力します。

awk -F "\t" 'BEGIN { OFS=FS }; { print $1, substr($2, 1, 75); }'

fedorquiで指摘されているように、切り捨てる必要のあるフィールドを置き換えることにより、3つ以上のフィールドを持つファイルを処理できます。

awk -F "\t" 'BEGIN { OFS=FS }; { $2=substr($2, 1, 75); print }'

substr必要に応じて、ループして複数のフィールドに適用できます。


@Stéphane、どの場合に追加が;必要ですか?
スティーブンキット、2015年

これらはPOSIXで必要です。現在、それらが必要とされる実装については知りませんが、POSIX要件を緩和するように依頼したところ、gawkメンテナによって拒否されました(ドキュメント内のすべての例に;があります)。
ステファンChazelas

ああ、知っておくと良い、ありがとう!したがって、仕様とドキュメントはすべての実装よりも厳密です...
Stephen Kitt

少なくとも私が知っているすべての実装(それほど多くない)。重要なのは、区切り記号を省略して非標準の構文を作成することです。したがって、現在および将来の実装では、それを抑制したり、それを利用する拡張機能を導入したりすることができます(/pattern/ {action} {exception-handling}たとえば、例外処理など)。これらを省略すること;がかなり一般的であることを考えると、今ではその可能性は非常に低くなります。
ステファンChazelas

4

移植可能/ POSIXly sed

tab=$(printf '\t')
sed "s/\($tab[^$tab]\{0,75\}\)[^$tab]*/\1/"

または、すべての列を切り捨てます:

sed "s/\([^$tab]\{75\}\)[^$tab]*/\1/g"

2

列が2つしかない場合:

sed -r 's/^([^\t]*\t)(.{0,75}).*/\1\2/'

{0,75}0から75文字までを選択することを意味します。
.* char 75以降の削除されたセクションです。


列が2 つ以上ある場合:

sed -r 's/^([^\t]*\t)([^\t]{0,75})[^\t]*(.*)/\1\2\3/' file

[^\t]* char 75以降の削除されたセクションです。


GNUを前提としていますsedし、それがPOSIXLY_CORRECT環境にない..です
ステファンChazelas
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.