如何根据另一个文件更改第3个记录字段?是否可以使用awk?
对不起,我是这个
的新手实施例: 记录
xxxx xxxx 1234 xxxx
xxxx xxxx 5678 xxxx
参数(另一个文件)
1234,9001
5678,9020
我的预期输出是
xxxx xxxx 9001 xxxx
xxxx xxxx 9020 xxxx
我的代码一瞥
#!/usr/bin/ksh
SRC=/home
FILE_LIST=`sqlplus -s idmp_stg/idmp_stg@DTPMPDR07_SUDB << EOF
set echo off head off feed off pagesize 0 trimspool on linesize 1000 colsep ,
spool output.csv
SELECT * from USAGE_TYPE_PARAM;
spool off;
exit;
EOF`
#Using while loop read values into variables from CSV file and create flat file
for each records
counter=1
while IFS=, read V1 V2
do
echo "${V1} ${V2}" > param_${counter}.txt
counter=$(( counter + 1 ))
done < output.csv
cd $SRC
ls D* | while read FILES
do
#--this supposed to change the 3rd field of the file but it doesn't show
#--an output, just zero byte file
awk 'NR==FNR{a[$1]=$2;next}{$3=a[$3]}1' FS="," output.csv FS=" " $FILES >
final_output.txt
done`
答案 0 :(得分:4)
$ awk 'NR==FNR{a[$1]=$2;next} {$3=a[$3];print}' <(tr , " " <Parameter) Records
xxxx xxxx 9001 xxxx
xxxx xxxx 9020 xxxx
说明:
一次拿一件:
NR==FNR{a[$1]=$2;next}
awk正在处理两个文件,一个接一个,一次一行。 NR是读取的总行数,FNR是当前文件中读取的行数。因此,当NR==FNR
时,我们位于第一个文件中,在本例中,它是参数。因此,只有在读取参数时才执行这些命令。 a[$1]=$2
创建一个字典,其键是第一个字段,其对应值是Parameter的第二个字段。 next
命令告诉awk忽略剩余的awk命令并跳到下一行。
{$3=a[$3];print}
由于上面的next
语句,这些命令仅在读取第二个文件时执行。他们将第三个字段更改为新值并打印该行。
<(tr , " " <Parameter)
与Records不同,文件Parameter以逗号分隔。在这里,translate命令tr
用于在awk
读取之前将其从逗号分隔转换为空格分隔。 <(...)
构造称为流程替换。
进程替换是所有shell都不支持的bash / ksh / zsh扩展。要在没有进程替换的情况下运行它:
$ tr , " " <Parameter | awk 'NR==FNR{a[$1]=$2;next} {$3=a[$3];print}' - Records
xxxx xxxx 9001 xxxx
xxxx xxxx 9020 xxxx
在此命令中,awk
的第一个文件参数为-
,表示stdin。 tr
的输出通过管道传输到awk
以提供此标准输入。
这与前面的解决方案相同,但避免了进程替换。
答案 1 :(得分:1)
使用awk
:
$ cat Records
xxxx xxxx 1234 xxxx
xxxx xxxx 5678 xxxx
$ cat Parameter
1234,9001
5678,9020
$ awk 'NR==FNR{a[$1]=$2;next}{$3=a[$3]}1' FS="," Parameter FS=" " Records
xxxx xxxx 9001 xxxx
xxxx xxxx 9020 xxxx
在文件名之前的末尾设置Field Separator变量,以便为该特定文件设置它。