awkのテンプレートに複数のFILENAMEを貼り付ける方法

awkのテンプレートに複数のFILENAMEを貼り付ける方法

テンプレートA.tsv(フィールド区切り記号= \ t)があります。

Name    data

B.txt や C.txt など、いくつかのファイルもあります。

次のように、ファイル名に(しかし新しいファイルに)ファイル名を印刷したいと思います。

Name    data
B
C

私はこれをしました:

template="A.tsv"
for bla in data/*.txt ; do
r="$(basename -s ".txt" $bla)"
( head -n 1 $template
awk -F'\t' -v OFS="\t" -v filename=$r '{print filename}' $bla ) > test_name.tsv  ;
done

しかし、それは私に次のものを与えます:

Name    data
C
C
C
C
C
C
C

私のコマンドにどのような問題があるのか​​ご存知ですか?

ありがとう

答え1

詳細な説明を含むスクリプト:

#!/bin/bash

#using the template variable is redundant, but
#I assume you want to use that lateron
template="A.tsv"
#write header from template and create file "output.txt"
#overwrites old version of "output.txt" if existing
head -n 1 ${template} > output.txt

#loop over files:
for bla in data/*.txt ; do
   #get basename without file suffix, add result to "output.txt" 
   basename -s ".txt" ${bla} >> output.txt
done

${variable}特にファイル名にはまたはを使用することをお勧めします"$varaible"。それ以外の場合、ファイル名にスペースなどが含まれているとスクリプトは中断されます。


なぜawk- 方法が失敗したのですか?

awk行単位で実行されます。あなたのコードには次のものがあります。

awk -v variable=$r '{print variable}' ${file}

したがって、10行のファイルがある場合は、上記のコマンドが10回実行され、10行の変数が生成されます。awk一度実行した後に停止するには、exitコマンドを実行する必要がある行を使用または指定します。

#execute command only on line no. 1
awk 'NR == 1 { print $1 }' file
#execute command and quit awk
awk '{ print 1 ; exit }'

元のスクリプトはどこで失敗しましたか?

>>出力はファイルに追加され、上書きされます>。スクリプトには、以下を含むループがあります。

( head -n 1 $template
awk [...] $bla ) > test_name.tsv

のすべての一致に対してdata/*txtこのコマンドが実行され、以前のバージョンが上書きされ、test_name.tsv最後のバージョンのみが実行されます。ループが実行されるたびにヘッダーを書き換える方法に注意してください。

関連情報