我想从文件(.txt)复制第一列,并将其替换为使用 Unix 代码分隔的文本中第二个文件的第一列。
输入文件格式文件1
01/01/2007
02/01/2007
03/01/2007
04/01/2007
文件2
20070101 10.2317 79.1638 6.0 26.7 20.9 0.8 14.0 98.6
20070102 10.2317 79.1638 5.6 26.5 20.8 1.9 13.6 98.0
20070103 10.2317 79.1638 7.5 27.7 20.8 0.1 15.8 96.4
20070104 10.2317 79.1638 8.1 26.0 19.6 0.0 15.5 94.1
需要输出
01/01/2007 10.2317 79.1638 6.0 26.7 20.9 0.8 14.0 98.6
02/01/2007 10.2317 79.1638 5.6 26.5 20.8 1.9 13.6 98.0
03/01/2007 10.2317 79.1638 7.5 27.7 20.8 0.1 15.8 96.4
04/01/2007 10.2317 79.1638 8.1 26.0 19.6 0.0 15.5 94.1
答案1
$ cut -d' ' -f 2- file2 | paste file1 -
将从cut
中删除第一列file2
(-f 2-
表示“仅输出字段(列)2 及以后”)。其结果将被传递到paste
将其内容放入file1
第一列中。命令-
中的是标准输入(本例中paste
为管道)上传递的任何内容的占位符。cut
一步步:
$ cut -d' ' -f 2- file2
10.2317 79.1638 6.0 26.7 20.9 0.8 14.0 98.6
10.2317 79.1638 5.6 26.5 20.8 1.9 13.6 98.0
10.2317 79.1638 7.5 27.7 20.8 0.1 15.8 96.4
10.2317 79.1638 8.1 26.0 19.6 0.0 15.5 94.1
$ cut -d' ' -f 2- file2 | paste file1 -
01/01/2007 10.2317 79.1638 6.0 26.7 20.9 0.8 14.0 98.6
02/01/2007 10.2317 79.1638 5.6 26.5 20.8 1.9 13.6 98.0
03/01/2007 10.2317 79.1638 7.5 27.7 20.8 0.1 15.8 96.4
04/01/2007 10.2317 79.1638 8.1 26.0 19.6 0.0 15.5 94.1
该cut
命令需要制表符分隔的输入,但由于我从您的问题中复制并粘贴,因此它是空格分隔的。如果原始数据实际上是制表符分隔的,请-d' '
从cut
命令中删除 。
默认情况下,该paste
命令将在第 1 列和第 2 列之间添加一个选项卡。如果您想要一个空格,请使用paste -d' ' file1 -
。
在另一个问题,有人询问如何使用file2
此处已有的日期,并完全删除第一个文件。
$ paste <( date -f <( cut -d ' ' -f 1 file2 ) +"%d/%m/%Y" ) \
<( cut -d ' ' -f 2- file2 )
01/01/2007 10.2317 79.1638 6.0 26.7 20.9 0.8 14.0 98.6
02/01/2007 10.2317 79.1638 5.6 26.5 20.8 1.9 13.6 98.0
03/01/2007 10.2317 79.1638 7.5 27.7 20.8 0.1 15.8 96.4
04/01/2007 10.2317 79.1638 8.1 26.0 19.6 0.0 15.5 94.1
请注意,这需要一个能够理解进程替换 ( ) 的 shell <( ... )
,例如bash
or ksh
,并且还需要 GNU 的date
.
可能需要做一些解释:
过程替代<( ... )
或多或少创建一个临时文件,其中包含括号内命令的输出(实际上是 下的 FIFO /dev/fd
)。所以整个命令会经过两步替换:
粘贴 <( 日期 -f剪切输出1+“%d/%m/%Y”)\ 从cut2输出
date -f filename
将读取文件中的日期filename
并根据给定的格式字符串格式化每个日期。
然后:
粘贴输出日期 从cut2输出
它将把各列粘贴在一起,其中的输出date
作为第一列,第二列的输出cut
作为其他列。
答案2
根据 awk
版本,您可以使用以下方法转换第一列:
awk '{$1=substr($0,7,2)"/"substr($0,5,2)"/"substr($0,1,4); print $0}' FILE2.csv
例子:
echo "20070101 10.2317 79.1638 6.0 26.7 20.9 0.8 14.0 98.6" | awk '{$1=substr($0,7,2)"/"substr($0,5,2)"/"substr($0,1,4); print $0}'
返回:
01/01/2007 10.2317 79.1638 6.0 26.7 20.9 0.8 14.0 98.6
笔记:
第一部分重新定义第一列的值
$1=substr($0,7,2)"/"substr($0,5,2)"/"substr($0,1,4)
并print $0
打印整行并重新定义第一列
答案3
您可以使用 awk 来实现此目的:
awk 'NR==FNR{a[++i]=$1;next}{$1=a[++k]; print}' file1 file2
NR==FNR
是一个模式含义:{a[++i]=$1;next}
对 file1 中的每条记录(即行)执行。
a[++i]=$1;next
方法:将记录的第一个字段(即行)与记录号(即file1的行号)的索引一起保存在数组中,然后读入下一条记录
$1=a[++k]; print
方法:将索引为 k 的数组内容复制到当前记录的第一个字段(即行)(始终是 file2 的第 k 条记录(即行))。