最後のフィールドを維持しながら、Linuxで複数の列名を短縮します。

最後のフィールドを維持しながら、Linuxで複数の列名を短縮します。

すべての列ヘッダーがパス名であるファイルがあります。各列ヘッダーを短くしたいと思います。~から次のようなもの:

/mydir/cat/dog/hen/test/block/sample1.so.rg.mk.bam /mydir/cat/dog/hen/test/block/sample2.so.rg.mk.bam

到着する:

sample1 sample2

Linuxでこれを行うにはどうすればよいですか?私のファイルには46〜100を超える列があるため、列名を手動で編集することはできません。私が望むファイル名の長さは、上記のようにそれぞれ7文字です。

ありがとう

ヘッダーにはファイル名が含まれます。各列ヘッダー/名前は次のとおりです。

/mydir/cat/dog/hen/test/block/sample1.so.rg.mk.bam 

私はその場にいたらいいのに

sample1

明確にするために、これは46列のテキストファイルです。各列ヘッダーまたは名前は、上記の長い文字列で表されます。各ヘッダーを7文字のバージョンに切りたいと思います。「サンプル1」…「サンプル46」

必須サンプルファイル(各列ヘッダーの下にデータを含む)

sample1 sample2 sample3 sample4 sample5 ...  

答え1

元のファイルを短い名前の新しいファイルにコピーする短いプログラムを作成します。元のファイルをアーカイブすると、問題が発生した場合にバックアップが可能になります。作成する内容は、おなじみの言語によって異なります。これはBashのようなシェルでも、Java、C、Pearl、Pythonなどのすべての言語でもかまいません。

以下はいくつかの疑似コードです。 old は元のファイル、new は新しいファイルです。新規

begin a loop to read each  line in old
   read line from old
   delete all characters from line up to and including the last "/"
   delete delete all characters from line after the first 7
//This is what you want to save unless it conflicts with a previously saved line
   determine if you have a conflict.
   if there is a conflict
      add a number to the end of line to make it unique
   save line to new
   end of loop

答え2

4つの列と2つの行を持つファイルがあるとしましょう。

host:~ # cat file2
/mydir/cat/dog/hen/test/block/sample1.so.rg.mk.bam /mydir/cat/dog/hen/test/block/sample2.so.rg.mk.bam /mydir/cat/dog/hen/test/block/sample3.so.rg.mk.bam /mydir/cat/dog/hen/test/block/sample4.so.rg.mk.bam
abc def ghi jkl

このコマンドは私にとって効果的です(非常に便利ではありませんが、それでも)。

host:~ # sed -i -e 's/^\///g' -e 's/[[:alnum:]]\+\///g' -e 's/\.[[:alnum:]]\+//g' -e 's/\///g' file2
host:~ # cat file2
sample1 sample2 sample3 sample4
abc def ghi jkl

より効率的な方法があると確信していますが、試してみることができます。

答え3

不要なサフィックスは常にあると仮定します。「.so.rg.mk.bam」、その後牛に似た一種の栄養 sed~のe評価注文するbasename最初の行でのみ実行するために使用できますファイル名、希望の出力に置き換えます。

sed -i '1s/.*/basename -as .so.rg.mk.bam -a &/e' filename

~のためGNUではない sedsをhead代わりに使用できます。

sed -i '1s/.*/'"$(basename -as .so.rg.mk.bam -a $(head -1 filename))"'/' filename

-

注:ファイルを変更せずに結果を表示するには、まずファイルを変更せずに試してください-i

答え4

awkを使用してヘッダーを処理できます。次のawkスクリプトが機能しますただ最初の行(NR==1)。行のすべてのフィールドを一度に繰り返します。各フィールドに対して次の手順を実行します。

  1. テキストの最初のインスタンスを見つけて、その/sampleインスタンスにテキストを切り取ります(および渡す/)。
  2. 期間の残りの部分で最初のインスタンスを見つけ、その期間から始めてその部分をクリーンアップします。
  3. 残りの部分が長すぎる場合は、sample必要に応じてテキストを切り取ります。どれくらい保持すべきかについての方程式は、「6プラスの最初の数字の位置 - 全長」です。
  4. フィールドを処理した後、末尾のスペースを含む印刷します。
  5. すべてのフィールドの反復が終了すると、改行文字を印刷します。

これにより、行の末尾に末尾のスペースが残ります。

awkスクリプト:

NR == 1 {
  for(i=1; i <= NF; i++) {
    tail=substr($i, 1 + match($i, "/sample"))   # delete up to the first instance of "/sample"
    tail=substr(tail, 1, index(tail, ".") - 1)  # find, then stop short of, the first period
    if (length(tail) > 7) {                     # if it's too long
        match(tail, "[0-9]")                    # find the first digit
                                                # trim the beginning down, then append the number
        tail=substr(tail, 1, 6 + RSTART - length(tail))substr(tail, RSTART)
    }
    printf tail" "
  }
  print ""
}

サンプル入力:

/mydir/cat/dog/hen/test/block/sample1.so.rg.mk.bam /mydir/cat/dog/hen/test/block/sample47.so.rg.mk.bam /mydir/cat/dog/hen/test/block/sample4631.so.rg.mk.bam /mydir/cat/dog/hen/test/block/sample1234567.so.rg.mk.bam 

出力例は次のとおりです。

sample1 sampl47 sam4631 1234567

関連情報