ファイル名と行番号のリストから特定の行を見つけて印刷します。

ファイル名と行番号のリストから特定の行を見つけて印刷します。

input.txt次の形式の複数のファイル名を含むファイルがあります。FILENAME_DATE_LINENUMBERinput.txtそのようなファイル名がたくさん含まれています。 ファイル名自体には正確に5つのアンダースコアがあります。

FILE_NAME_1.DAT_20180123_4
FILE_NAME_2.DAT_20180123_5
FILE_NAME_3.DAT_20180123_6
FILE_NAME_4.DAT_20180123_7

すべてのファイルはで始まります。解析して各ファイル名を繰り返し、FILENAMEと指定された行番号(FILENAME)を印刷したいとinput.txt思います。input.txtoutput.txt

私はsedまたはawkを使用し、次のコマンドがアクションを実行することを知っています。

awk 'FNR==LINENUMBER {print FILENAME, $0}' *.txt >output.txt

しかし、どのようにファイルを繰り返しinput.txtてFILENAMEを見つけ、FILENAMEからLINENUMBERを抽出するかoutput.txt

指定されたFILENAMEはinput.txtサブディレクトリの1つにありますinput.txt。この場所のサブディレクトリの1つ(1レベル)内のinput.txtにFILENAMEを持つファイルは1つしかありませんinput.txt

DIR
├── input.txt
│   ├── DIR1
│   │   ├── FILE_NAME_1.DAT
│   ├── DIR2
│   │   ├── FILE_NAME_2.DAT
│   ├── DIR3
│   │   ├── FILE_NAME_3.DAT

output.txtのように印刷する必要があります。

FILENAME
LINE( Extracted from FILENAME present in input.txt )

ベストアンサー1

#!/bin/bash                                                                                   

do_one() {
    # two args: $1=filename_no_dir $2=line_number                                             
    # Find the single filename                                                                
    eval file=*"/$1"
    echo $1
    # $. == line number                                                                       
    perl -ne 'chomp; $.=='"$2"' and print "LINE($_)\n"' $file
}
export -f do_one

# Generate som test data                                                                      
parallel 'mkdir DIR{}; seq 100 110 >DIR{}/FILE_NAME_{}.DAT' ::: {1..4}

# Test input.txt                                                                              
cat <<EOF |                                                                                   
FILE_NAME_1.DAT_20180123_4                                                                    
FILE_NAME_2.DAT_20180123_5                                                                    
FILE_NAME_3.DAT_20180123_6                                                                    
FILE_NAME_4.DAT_20180123_7                                                                    
EOF                                                                                           
  # Remove _YYYYMMDD.* to get filename, and .*_ to get line number                            
  parallel do_one '{= s/_201\d\d\d\d\d.*// =}' '{= s/.*_// =}'

出力:

FILE_NAME_1.DAT
LINE(103)
FILE_NAME_2.DAT
LINE(104)
FILE_NAME_3.DAT
LINE(105)
FILE_NAME_4.DAT
LINE(106)

おすすめ記事