我有一个文本文件,正在尝试提取文件第一行(或行)中的数据,其中每个数据都保存为列表(因此每个点都保存在它自己的行上)在新文件中。
示例数据.txt:
Name Col Samp1 Samp2 Samp3 Samp4 Samp5 Samp6
Car1 Red 49.3 43.2 54.3 52.3 12.5 76.8
Car2 Blu 56.3 12.4 85.4 67.1 24.5 32.5
and so on..
我希望一个新列表看起来像这样,并保存到一个名为 samps 的新文件中.txt:
Samp1
Samp2
Samp3
Samp4
Samp5
Samp6
我对 shell 脚本非常陌生,可以使用任何人都可以提供的所有帮助。
read -a
将行读入数组,然后使用 for
循环访问数组元素。有关更多详细信息,请参阅help
。
这将解决问题:
$ head -1 data.txt | grep -o 'Samp[0-9]*'
Samp1
Samp2
Samp3
Samp4
Samp5
Samp6
解释:
显示文件的第一行:
head -1 data.txt
|
获取上一个命令的输出,并将其用作下一个命令的输入(称为管道)。打印给定
regex
的匹配项:grep -o 'Samp[0-9]*'
regex
'Samp[0-9]*'
将匹配任何以Samp
开头后跟任何数字的字符串。
要将输出保存到samps.txt
请使用重定向运算符>
:
$ head -1 data.txt | grep -o 'Samp[0-9]*' > samps.txt
这将适用于任何列标题,而不仅仅是与'Samp[0-9]*'
匹配的列标题:
$ head -1 data.txt | grep -o 'w*' | tail -n +3 > samps.txt
grep -o 'w*'
匹配单词,tail -n +3
显示从第三行开始的所有行(即不显示前两列标题)。
将第一行读入变量
read -r FIRSTLINE < filename
将字符串拆分为单词
WORDS=( $FIRSTLINE )
循环遍历单词并将它们输出到文件
for WORD in ${WORDS[@]}
do
echo $WORD >> outputfilename
done
在您的情况下,您希望删除前两列值。您可以通过在 for 语句中使用 ${WORDS[@]:2
对数组进行切片。或者,您可以在将值回显到文件之前测试 for 循环中的值。
在处理带有字段的文本文件时,您可能会发现awk是一个有价值的工具:
awk 'NR==1 { for(i=3;i<=NF;i++) print $i }' file
结果:
Samp1
Samp2
Samp3
Samp4
Samp5
Samp6
解释:
NR is short for the number of rows.
NF is short for the number of fields in the row.
仅使用 bash:
set -- $(head -1 data.txt) # save the words in the first line as $1,$2,...
shift 2 # discard the first two words
printf '%sn' "$@" > samps.txt # print each remaining word on its own line
我投票支持伊格纳西奥·巴斯克斯-艾布拉姆斯的答案,因为它是最好的选择,只使用纯bash
。由于他没有给出一个完全有效的例子,这里有一个:
read -a samps < "myfile.txt"
printf "%sn" "${samps[@]:2}"
输出:
Samp1
Samp2
Samp3
Samp4
Samp5
Samp6