在bash中使用参数文本文件

时间:2014-09-18 04:01:38

标签: bash unix awk parameters grep

如何根据另一个文件更改第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`

2 个答案:

答案 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读取之前将其从逗号分隔转换为空格分隔。 <(...)构造称为流程替换。

POSIX或mksh或pdsh

进程替换是所有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变量,以便为该特定文件设置它。