テンプレート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
最後のバージョンのみが実行されます。ループが実行されるたびにヘッダーを書き換える方法に注意してください。