
テキストファイルの特定の列(私の場合は列4)が新しいテキストファイルの最後の列として追加されるループを作成したいと思います。 4番目の列をインポートし、新しいテキストファイル(タブで区切られた列)に追加したい合計500個のテキストファイル(V1-V500)があります。すべてのテキストファイルの行数は同じです。さらに、追加された列のヘッダーには、その列が最初に指定されたテキストファイルのファイル名を含める必要があります。私はawkとforループを使ってコマンドラインを設定してみましたが、どのコマンドも機能しません。以前のコマンドラインに基づいてコマンドラインを試しました。郵便はがき。私は利用可能なGNUツールを使用してLinuxで作業しています。
例: V1 テキストファイル
header1 header2 header3 header4
1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16
V2テキストファイル:
header1 header2 header3 header4
17 25 21 29
18 26 22 30
19 27 23 31
20 28 24 32
新しいテキストファイル:
V1 V2
13 29
14 30
15 31
16 32
ご協力ありがとうございます!
答え1
awk
すべてのファイルを解析します。
awk -F'\t' -v OFS='\t' '{
x = (FNR==1 ? FILENAME : $4)
a[FNR] = (FNR==NR ? x : a[FNR] OFS x)
}
END {
for (i=1;i<=FNR;i++) print a[i]
}' V{1..500}
x
a
これは私たちが構築するすべてのラインと新しいラインにつながるものです。どちらも割り当てを使用します。条件式。FNR
現在の入力ファイルの行番号とNR
総行数。FNR==NR
「最初のファイルを解析するとき」を意味します。また、タブで区切られた入力と出力を想定しました。
答え2
非 awk ソリューション:
#!/bin/bash
for num in {1..500}; do
echo V$num > temp_$num #put the filename as header
< V$num tail -n+2 | cut -f4 >> temp_$num #get the contents of column 4
if [[ -f V_new ]]; then #if not first iteration
paste V_new temp_$num > temp #combine previous files with current file
mv temp V_new
else # if first iteration
mv temp_$num V_new
fi
done
答え3
awkや他のツールを使ってこれを行うことができますが、ここではより簡単なアプローチをお勧めします。
$ printf 'paste ' > script
$ printf "<(awk 'NR==1{print FILENAME; next}{print \$4}' %s) \\\\\n" V{1..500} >> script
$ sh ./script
これにより、paste
ファイルにscript
次のような複雑なコマンドが生成されます。
$ head script
paste <(awk 'NR==1{print FILENAME; next}{print $4}' V1) \
<(awk 'NR==1{print FILENAME; next}{print $4}' V2) \
<(awk 'NR==1{print FILENAME; next}{print $4}' V3) \
<(awk 'NR==1{print FILENAME; next}{print $4}' V4) \
<(awk 'NR==1{print FILENAME; next}{print $4}' V5) \
<(awk 'NR==1{print FILENAME; next}{print $4}' V6) \
<(awk 'NR==1{print FILENAME; next}{print $4}' V7) \
<(awk 'NR==1{print FILENAME; next}{print $4}' V8) \
<(awk 'NR==1{print FILENAME; next}{print $4}' V9) \
<(awk 'NR==1{print FILENAME; next}{print $4}' V10) \
したがって、script
awkコマンドを使用して実行が実行され、500個の入力ファイルのそれぞれの4番目の列が抽出されます。paste
例の2つのファイルを使用すると、次のものが生成されます。
$ printf 'paste ' > script
$ printf "<(awk 'NR==1{print FILENAME; next}{print \$4}' %s) \\\\\n" V* >> script
$ sh ./script
V1 V2
13 29
14 30
15 31
16 32
答え4
awkを使用してforループに貼り付けたソリューション:
- 最初のファイルの列4を作成します(ファイル名をヘッダーとして使用)
NEW
。
awk -F'\t' 'NR==1{print FILENAME; next} {print $4}' V1 > NEW
NEW
forループに別のファイル(ファイル名をヘッダーとして使用)の列4を追加します。一時ファイル(temp
)を使用して出力を収集し、その内容を各NEW
反復に移動します。
for file in V{2..500}; do
paste NEW <(awk -F'\t' 'NR==1{print FILENAME; next} {print $4}' $file) > temp && mv -f temp NEW
done