Как создать новый файл с определенными столбцами из файлов в нескольких папках в Linux?

Ни один из приведенных выше ответов мне не помог, а подход lsscsi на самом деле дал неверный ответ из-за расхождений между номерами шин SCSI и номерами ATA. В системе с 21 -диском у меня было много сообщений системного журнала о проблемах с нарушениями ATA18 (HSM ). Какой диск вызывал эти ошибки? Некоторые из них были USB-накопителями, что значительно усложняло ситуацию. Мне нужен был отчет о том, как каждый SCSI-диск подключен к системе, и я написал приведенный ниже сценарий, который дает табличные списки для всех SCSI-дисков (/dev/s[dr]? )независимо от того, ATA или USB.

Затем, когда все диски были полностью учтены -, я был удивлен, увидев, что мои ошибки ATA не имеют ничего общего с какими-либо моими дисками. Я задал неправильный вопрос, и я думаю, что другие могут легко попасть в ту же ловушку, поэтому я упоминаю об этом здесь.Затем я использовал второй подход, определяющий аппаратное обеспечение, которое генерировало сообщения о нарушении HSM, также подробно описанные в документации, представленной в приведенном ниже сценарии.

#!/bin/bash

## This script lists the ata and usb bus numbers, as well as the
## overall "host" numbers, of each scsi disk.  The same information
## appears formatted four ways, redundantly, for ease of lookup by (1)
## device lettername, (2) ata bus, (3) usb bus, or (4) overall "host"
## number.

#######################################################

## Q: What if you're looking for an ATA bus number, e.g. ata18, that
##    isn't listed by this script?

## (1) Well, it's probably not a SCSI disk, at least not one that's
##     operating.

## (2) Somewhere in /sys you can find a mapping from the ATA bus
##     number to some overall host number, such as host17.  For example,
##     if you're looking for ata18, you can use a find command...

##     find /sys -type l -exec bash -c 'link=`readlink "$0"`; if [[ "$link" =~ /ata18/ ]] ; then echo $link ; fi' {} \;

##    ...which, after some delay, might yield output something like this:

##   ../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/ata_port/ata18
##   ../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/host17/target17:0:0/17:0:0:0/scsi_generic/sg5
##   ../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/link18/dev18.0/ata_device/dev18.0
##   ../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/host17/scsi_host/host17
##   ../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/link18/ata_link/link18
##   ../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/host17/target17:0:0/17:0:0:0/bsg/17:0:0:0
##   ../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/host17/target17:0:0/17:0:0:0/scsi_device/17:0:0:0
##   ../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/host17/target17:0:0/17:0:0:0/scsi_generic/sg5
##   ../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/host17/target17:0:0/17:0:0:0/bsg/17:0:0:0
##   ../../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/host17/target17:0:0/17:0:0:0
##   ../../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/host17
##   ../../../devices/pci0000:00/0000:00:02.0/0000:02:00.0/ata18/host17/target17:0:0

##     Then you might notice the "/host17/" or "scsi_device/17:0:0:0"
##     in the above output lines, and look in the output of...

##     lshw

##    .. for "scsi17" or "17:0" or such, and discover, somewhere in it...

##    ...
##        *-scsi:5
##           physical id: 8
##           logical name: scsi17
##           capabilities: emulated
##         *-processor UNCLAIMED
##              description: SCSI Processor
##              product: 91xx Config
##              vendor: Marvell
##              physical id: 0.0.0
##              bus info: scsi@17:0.0.0
##              version: 1.01
##              capabilities: removable
##              configuration: ansiversion=5
##    ...

##...thus learning that ata18 corresponds to an unclaimed device (but
## not actually a disk).  Q.E.D.

## P.S. the lsscsi command yields the following, which might lead
## one to think that the problem was being caused by a CD-ROM drive
## (SCSI18:0) rather than emanating from the Marvell (SCSI17:0):

## [17:0:0:0]   process Marvell  91xx Config      1.01  -        
## [18:0:0:0]   cd/dvd  HL-DT-ST DVDRAM GH22NS90  HN00  /dev/sr0 

##... but ATA != SCSI, and 17 != 18.  The CD/DVD drive was ATA19, 
## actually.  You can still use lsscsi, but
## bear in mind that what you're seeing in the left column
## is *not* ATA numbers but rather SCSI bus numbers, and the two
## are not to be confused.
#######################################################

blockDevsDir=/sys/dev/block

declare -A scsiDevLetters
declare -A hostNumbers
declare -A ataNumbers
declare -A usbNumbers

scsiDevLetterRE='/s(d[a-z]|r[0-9])$'
hostNumberRE='/host([0-9]+)/'
ataNumberRE='/ata([0-9]+)/'
usbNumberRE='/usb([0-9]+)/'

cd "$blockDevsDir"
for busid in `ls -1` ; do
    linkval=`readlink "$busid" `
    if [[ "$linkval" =~ $scsiDevLetterRE ]] ; then
        scsiDevLetter="${BASH_REMATCH[1]}"
        if [[ "$linkval" =~ $hostNumberRE ]] ; then
            hostNumber="${BASH_REMATCH[1]}"
            if [[ "$linkval" =~ $ataNumberRE ]] ; then
                ataNumber="${BASH_REMATCH[1]}"
                scsiDevLetters[$scsiDevLetter]=`printf 'ata%-2.2s  host%-2.2s' "${ataNumber}" "${hostNumber}"`
                hostNumbers[${hostNumber}]=`printf '/dev/sd%s  ata%-2.2s' "${scsiDevLetter}" "${ataNumber}"`
                ataNumbers[${ataNumber}]=`printf '/dev/sd%s  host%-2.2s' "${scsiDevLetter}" "${hostNumber}"`
            elif [[ "$linkval" =~ $usbNumberRE ]] ; then
                usbNumber="${BASH_REMATCH[1]}"
                scsiDevLetters[$scsiDevLetter]=`printf 'usb%-2.2s  host%-2.2s' "${usbNumber}" "${hostNumber}"`
                hostNumbers[${hostNumber}]=`printf '/dev/sd%s  usb%-2.2s' "${scsiDevLetter}" "${usbNumber}"`

                existingUsbValue="${usbNumbers[${usbNumber}]}"
                addedUsbValue=`printf '/dev/sd%s  host%-2.2s' "${scsiDevLetter}" "${hostNumber}"`
                if [ -n "$existingUsbValue" ] ; then
                    usbNumbers[${usbNumber}]="$existingUsbValue | $addedUsbValue"
                else
                    usbNumbers[${usbNumber}]="$addedUsbValue"
        fi
            else
        echo "Neither ata nor usb: /dev/sd${scsiDevLetter} (host${hostNumber}) !"
            fi
        else
        echo "No host number for /dev/sd${scsiDevLetter}"
        fi
    fi
done    

echo '/dev/sd?'
echo '--------'
for scsiDevLetter in `echo "${!scsiDevLetters[*]}" | tr ' ' '\n' | sort` ; do
    echo "/dev/sd${scsiDevLetter}    ${scsiDevLetters[$scsiDevLetter]}"
done
echo
echo 'ataNN'
echo '-----'
for ataNumber in `echo "${!ataNumbers[*]}" | tr ' ' '\n' | sort -n` ; do
    printf 'ata%-2.2s    %s\n' "$ataNumber" "${ataNumbers[$ataNumber]}"
done
echo
echo 'usbNN'
echo '-----'
for usbNumber in `echo "${!usbNumbers[*]}" | tr ' ' '\n' | sort -n` ; do
    printf 'usb%-2.2s    %s\n' "$usbNumber" "${usbNumbers[$usbNumber]}"
done
echo
echo 'hostNN'
echo '------'
for hostNumber in `echo "${!hostNumbers[*]}" | tr ' ' '\n' | sort -n` ; do
    printf 'host%-2.2s    %s\n' "$hostNumber" "${hostNumbers[$hostNumber]}"
done
0
04.12.2020, 17:41
1 ответ
$ cat tst.awk
BEGIN {
    FS=OFS="\t"
    numCols = 2
}
{
    if ( FNR == 1 ) {
        numCols++
        val = FILENAME
        sub("/[^/]+$","",val)
        sub(".*/","",val)
    }
    else {
        val = $4
    }
    vals[FNR,1] = $1
    vals[FNR,2] = $2
    vals[FNR,numCols] = val
}
END {
    for (rowNr=1; rowNr<=FNR; rowNr++) {
        for (colNr=1; colNr<=numCols; colNr++) {
            printf "%s%s", vals[rowNr,colNr], (colNr<numCols ? OFS : ORS)
        }
    }
}

$ awk -f tst.awk */estimate.tsv
target_id       length  SOB33D  SOB43E
ENST00000456328.2       1657    0       0.174591
ENST00000450305.2       632     0       0
ENST00000488147.1       1351    0.492522        7.70424
ENST00000619216.1       68      0.70395 0.295008
ENST00000473358.1       712     0       0
ENST00000469289.1       535     0       0

Описанное выше было выполнено с использованием этого ввода (все пробелы являются вкладками):

$ head */estimate.tsv
==> SOB33D/estimate.tsv <==
target_id       length  eff_length      est_counts
ENST00000456328.2       1657    1525.05 0
ENST00000450305.2       632     500.105 0
ENST00000488147.1       1351    1219.05 0.492522
ENST00000619216.1       68      12.9174 0.70395
ENST00000473358.1       712     580.105 0
ENST00000469289.1       535     403.105 0

==> SOB43E/estimate.tsv <==
target_id       length  eff_length      est_counts
ENST00000456328.2       1657    1525.05 0.174591
ENST00000450305.2       632     500.105 0
ENST00000488147.1       1351    1219.05 7.70424
ENST00000619216.1       68      12.9174 0.295008
ENST00000473358.1       712     580.105 0
ENST00000469289.1       535     403.105 0
3
18.03.2021, 22:45

Теги

Похожие вопросы