我的输入文件是allresponses_11.txt
,其中包含带标题的数据:
ID NAME LOC PH
T1 BA KA 99
T2 GT HS 98
我想要输出如下。
seq_num file_num hname
1 11 ID
2 11 NAME
3 11 LOC
4 11 PH
请帮我在unix中获得所需的输出。文件名需要动态传递。
在你的帮助下,我制作了如下脚本,但它为每个单词提供了标题输出。我的标题按标签分隔,标题内有空格。
#!/bin/ksh
export INFAHOME=/informat/PowerCenter/9.1.0/server/infa_shared
export SRCDIR=${INFAHOME}/SrcFiles/CSI/INCOMING
export filename=${SRCDIR}/AllResponses_11003_6_7_20132_17_33AM1.txt
export filenum=$(echo $filename | tr -dc 0-9 |cut -c 1-5)
echo seq_num file_num hname
cnt=1
for h in $(head -1 "$filename")
do
echo $cnt $filenum $h
cnt=$((cnt+1))
done
我的输出应该是
SEQ_NUM FILE_NUM HNAME
1 11003 TOTAL COUNT
2 11003 FINAL DAY
3 11003 LADT COUNT
我的源文件分隔符是制表符,但我的标题列名称有空格。
答案 0 :(得分:1)
您的文件约会惯例:
export filename=${SRCDIR}/AllResponses_11003_6_7_20132_17_33AM1.txt
太可怕了。如果你使用如下符号:
,这将使你的生活更轻松filename=${SRCDIR}/AllResponses_11003_2013_06_07_02_17_33_1.txt
或更紧凑的表示法,例如:
filename=${SRCDIR}/AllResponses_11003_20130607_021733_1.txt
然而,这与现有讨论相关。请注意,您不需要在太阳下导出每个变量 - 在此脚本中,不需要导出任何导出的变量。
您的路径名称:
export INFAHOME=/informat/PowerCenter/9.1.0/server/infa_shared
包含三个数字,您在代码中未考虑这些数字来提取文件的序列号。
我可能会根据您的需要使用awk
来处理数据,使用如下脚本的变体:
#!/bin/bash
INFAHOME=/informat/PowerCenter/9.1.0/server/infa_shared
SRCDIR=${INFAHOME}/SrcFiles/CSI/INCOMING
filename=${SRCDIR}/AllResponses_11003_6_7_20132_17_33AM1.txt
filenum=$(basename $filename | sed 's/^[^_]*_\([0-9][0-9]*\)_.*/\1/')
echo seq_num file_num hname
sed 1q "$filename" |
awk -F $'\t' -v filenum=$filenum '{ for (i = 1; i <= NF; i++) print i, filenum, $i;}'
我已将'shell'切换为bash
以允许使用$'\t'
将标签嵌入awk
命令行。你可以很好地使用ksh
代替单引号,制表符和另一个单引号,但很难在SO Markdown中区分空格与制表符。
filenum
的分配使用basename
来获取文件名。 bash
afficionado会写${filename##*/}
代替;这可能也适用于ksh
。随后的sed
命令会在一系列非下划线后捕获由下划线包围的一串数字。
awk
命令使用选项卡作为输入字段分隔符,从而处理以制表符分隔的包含空格的标题元素。
给定一个数据文件,例如:
TOTAL COUNT FINAL DAY LADT COUNT
100 Friday 102
(其中多个空白的每个序列是数据文件中的一个选项卡)和filenum=11003
,输出为:
seq_num file_num hname
1 11003 TOTAL COUNT
2 11003 FINAL DAY
3 11003 LADT COUNT
如果您也想要以制表符分隔的输出列,请将OFS="\t";
添加到awk
脚本中:
awk -F$'\t' -v filenum=11003 '{ OFS="\t"; for (i = 1; i <= NF; i++) print i, filenum, $i;}'
1 11003 TOTAL COUNT
2 11003 FINAL DAY
3 11003 LADT COUNT
sed 1q
命令不是绝对必要的。你可以awk
忽略除第一行输入之外的所有内容:
awk -F $'\t' -v filenum=$filenum 'NR==1 { for (i = 1; i <= NF; i++)
print i, filenum, $i;
}'
如果您愿意,可以awk
打印标题;如果需要以制表符分隔,这可能有价值。
答案 1 :(得分:0)
虽然你的问题有点缺乏细节,但我认为这至少可以达到你想要的目的:
filename=allresponses_11.txt
filenum=$(echo ${filename} | tr -dc 0-9)
echo "seq_num file_num hname"
for h in $(head -1 ${filename})
do
echo "${filenum} ${h}"
done | cat -n
答案 2 :(得分:0)
您可以使用awk来获取答案
awk -F $'\ t'-v filenum = $ filenum'{for(i = 1; i <= NF; i ++)打印i,filenum,$ i;}'