提问人:JJRudder 提问时间:7/18/2023 最后编辑:JJRudder 更新时间:7/19/2023 访问量:107
尝试在文件中的每一行上运行 awk 命令,并将当前行替换为 awk 的结果
Trying to run an awk command on each line in a file, and replace the current line with the results of the awk
问:
我正在尝试循环浏览一个文件,并使用每一行搜索不同的 csv 文件(特别是搜索第 2 列),并为每个条目返回该文件中的第 4 列。然后,我想用新结果替换当前行。输入文件如下所示:
Ant
Bat
Carp
Dog
目前我正在使用此代码:
while read -r line
do
awk -v line="\"$line\"" -F, '$2 ~ line' search.csv | awk -F, '{print $4}' >> $filename
done < $filename
这会将新行添加到文件的末尾,因此我得到以下输出:
Ant
Bat
Carp
Dog
"Insect"
"Mammal"
"Fish"
"Mammal"
如何只获得第二个列表(引号中的单词)?
编辑:
以下是来自 search.csv 的示例数据:
"A0001","Dog","Canine","Mammal","4","Y","N"
更新#1
search.csv 文件的每个条目都用引号括起来。我是这样编辑我的awk的:
awk -F, 'NR==FNR {wrds["\""$1"\""]; next} $2 in wrds {print ($4 > "temporary.txt")}' "filename.txt" search.csv
现在,它将每行打印一个 0 到屏幕上。临时 .txt 文件仍为空:
0
0
0
0
答:
1赞
anubhava
7/18/2023
#1
你不需要 shell 循环。只需在单个 awk 命令中执行此操作,如下所示:
awk -F, 'NR==FNR {wrds["\"" $1 "\""]; next}
$2 in wrds {print $4 > "tmpFile"}' "$filename" search.csv
手动验证输出,满意后运行:tmpFile
mv tmpFile "$filename"
替换原始输入文件。
评论
1赞
JJRudder
7/19/2023
我已经尝试了这个命令,但它没有做任何事情。没有输出,tmp文件为空: awk -F, 'NR==FNR{wrds[$1];下一页}$2 in wrds{print ($4 > “tmpfile”)}' filename.txt search.csv
0赞
anubhava
7/19/2023
通过编辑您的问题提供示例数据search.csv
1赞
glenn jackman
7/19/2023
@JJRudder,请确保您的文件没有 DOS 样式的行尾\r\n
0赞
anubhava
7/19/2023
此外,还可以更改带引号的单元格值。如果 csv 文件有,则将其更改为"Dog"
awk
NR==FNR {wrds["\"" $1 "\""]; next}
0赞
anubhava
7/19/2023
@JJRudder:现在试试我更新的答案。
2赞
markp-fuso
7/19/2023
#2
看看OP最新的代码尝试:
awk -F, 'NR==FNR {wrds["\""$1"\""]; next} $2 in wrds {print ($4 > "temporary.txt")}' "filename.txt" search.csv
OP 指出这在终端上生成一个并且是空的。注意:当我运行 OP 的代码时,它确实在控制台上生成了一个,但它甚至没有创建一个名为 .0
temporary.txt
0
temporary.txt
主要问题如下:
print ($4 > "temporary.txt")
哪里:
- 首先处理 parens 的内容,所以......
($4 > "temporary.txt")
作为比较/条件处理,即比较第 4 个字段以查看它是否“大于”文本字符串"temporary.txt"
- 在这种情况下,and says is not so 结果是 'false',它由 a 表示,所以......
$4 == "Mammal"
awk
"Mammal"
> "temporary.txt"
awk
0
- 向控制台发送一个(又名“false”)...
print
0
- 当然,不会将任何内容写入任何文件(即,不会创建命名的文件,更不用说写入了)
temporary.txt
快速解决方法是删除 parens,以便发送到名为 的文件,即:print
$4
temporary.txt
$ awk -F, 'NR==FNR {wrds["\""$1"\""]; next} $2 in wrds {print $4 > "temporary.txt"}' "filename.txt" search.csv
$ <<=== no ouput, no '0'
$ cat temporary.txt
"Mammal
当您希望脚本将输出发送到动态生成的输出文件集或可变数量时,通常使用从脚本中指定输出文件名称的方法。awk
awk
在这种情况下,由于所有输出都转到同一个文件,因此典型的方法是在命令行(即脚本外部)定义输出文件;这往往会使脚本更简洁一些,例如:temporary.txt
awk
awk
awk -F, 'NR==FNR {wrds["\""$1"\""]; next} $2 in wrds {print $4}' filename.txt search.csv > temporary.txt
^^^^^^^^ ^^^^^^^^^^^^^
评论
search.csv
while/read
$filename
awk
$filename
$filename
$filename