它是可能的替换价值的一个单元在一个csv文件使用的查询,sed或两个

0

的问题

我已经写下的命令

#!/bin/bash
awk -v value=$newvalue -v row=$rownum -v col=1 'BEGIN{FS=OFS=","} NR==row {$col=value}1' "${file}".csv >> temp.csv && mv temp.csv "${file}".csv

样本输入的 文件。csv

Header,1
Field1,Field2,Field3
1,ABC,4567
2,XYZ,7890

Assuiming $newvalue=3,$rownum=4 col=1,则上述码将更换:

需要输出

Header,1
Field1,Field2,Field3
1,ABC,4567
3,XYZ,7890

所以如果我知道的行列,是否有可能以代替上述的价值使用的查询,sed?

Edit1:Field3总将有一个独特的价值为他们各自的行中。 (情况下,信息有助于反正)

bash csv git-bash linux
2021-11-24 06:52:47
3

最好的答案

1

假设你CSV文件作为简单的为什么你告诉(没有逗号在引述领域),和你 newvalue 不包含符sed会解释中的一种特殊的方式(例如号、斜线或斜杠),下面的工作应该只是sed(测试与GNU sed):

sed -Ei "$rownum s/[^,]*/$newvalue/$col" file.csv

演示:

$ cat file.csv
Header,1
Field1,Field2,Field3
1,ABC,4567
3,XYZ,7890
$ rownum=3
$ col=2
$ newvalue="NEW"
$ sed -Ei "$rownum s/[^,]*/$newvalue/$col" file.csv
$ cat file.csv
Header,1
Field1,Field2,Field3
1,NEW,4567
3,XYZ,7890

说明: $rownum 被用作为地址(在这里的线路数目)在何处应用以下指令。 s 是sed替代的命令。 [^,]* 是的经常表达的搜索和替代:尽可能长串不含一个逗号。 $newvalue 是的更换字符串。 $col 是的发生替换。

如果 newvalue 可以包含号、斜线或斜杠,我们必须清理它,首先:

sanitizednewvalue=$(sed -E 's/([/\&])/\\\1/g' <<< "$newvalue")
sed -Ei "$rownum s/[^,]*/$sanitizednewvalue/$col" file.csv

演示:

$ newvalue='NEW&\/&NEW'
$ sanitizednewvalue=$(sed -E 's/([/\&])/\\\1/g' <<< "$newvalue")
$ echo "$sanitizednewvalue"
NEW\&\\\/\&NEW
$ sed -Ei "$rownum s/[^,]*/$sanitizednewvalue/$col" file.csv
$ cat file.csv
Header,1
Field1,Field2,Field3
1,NEW&\/&NEW,4567
3,XYZ,7890
2021-11-24 11:13:43

这并工作。 只是一些虽然我不知道在此之前回答的`[^,]*`但是如果 sed 是能够取代一个特定的细胞,然后我们为什么要包括[^,]*. 我没有尝试 sed -Ei "$rownum s/$newvalue/$col" file.csv 它扔了一个错误,但想知道更多关于这一点。 任何资源来阅读时将是有帮助的。
Helium

我们需要`[^,]*`,因为它是什么样的定义是什么一个 小区 。 sed不是一个CSV处理器,这是一个任何文本处理器。 因此,它不知道你叫什么 细胞 。 我们必须告诉它。 Sed替代的命令(s)是解释的深度详情在sed手册,你会很容易找到(如果正在GNU/Linux或mac os尝试 man sed 或者,更好, info sed). 替代的命令你试图在语法上的错误,这样的错误。
Renaud Pacalet

是啊,这使得更有意义,现在,当把这样的。
Helium
1

sed怎:

#!/bin/bash

newvalue=3
rownum=4
col=1

sed -i -E "${rownum} s/(([^,]+,){$((col-1))})[^,]+/\\1${newvalue}/" file.csv

结果, file.csv

Header,1
Field1,Field2,Field3
1,ABC,4567
3,XYZ,7890
  • ${rownum} 相匹配的行号。
  • (([^,]+,){n}) 相匹配的n次重复集团 非逗号字符后加一个逗号。 然后,它应该是子串 之前的目标(被取代)列的分配 ncol - 1.
2021-11-24 07:21:19

虽然这不工作,这不是一个比较复杂的方式做事情相比如何Renauld的答复。 喜欢为什么我们需要相匹配的n-时间重复的,如果我们可以而不是直接替代吗? 尽管如此有用的
Helium
0

让我们努力实现sed命令

让我们考虑这样CSV文件与以下内容:

$ cat file

Solaris,25,11
Ubuntu,31,2
Fedora,21,3
LinuxMint,45,4
RedHat,12,5
  1. 删除第1段或列:
$ sed 's/[^,]*,//' file

25,11
31,2
21,3
45,4
12,5

这经常表达的搜索顺序的非逗号([^,]*)人物和将其删除,其结果在第1段得到清除。

  1. 只打印的最后一个领域,或除外的所有领域的最后一个领域:
$ sed 's/.*,//' file

11
2
3
4
5

这regex消除一切直到最后一个逗号(.*,) 其结果中删除所有领域,除了最后一个领域。

  1. 只打印第1栏:
$ sed 's/,.*//' file

Solaris
Ubuntu
Fedora
LinuxMint
RedHat

这regex(,.*) 删除的字符从第1逗号,直到结束导致删除所有领域,除了最后一个领域。

  1. 删除第2栏:
$ sed 's/,[^,]*,/,/' file

Solaris,11
Ubuntu,2
Fedora,3
LinuxMint,4
RedHat,5

Regex(,[^,]*,)搜索一个逗号和序列的字符后加一个逗号,其结果匹配的第2列,并取代这一模式匹配的只有一个逗号,最终结束在删除第2列。

注:删除该领域中变得更加强硬,在sed由于每一个领域都有配字面上。

  1. 只打印第2栏:
$ sed 's/[^,]*,\([^,]*\).*/\1/' file

25
31
21
45
12

Regex匹配的第一个领域,第二领域和其余部分,然而组第2段单独的。 整个线是现在替换第2段(\1),因此只有第2段得到显示。

  1. 只打印线在最后一栏是一个单一的数字数:
$ sed -n '/.*,[0-9]$/p' file

Ubuntu,31,2
Fedora,21,3
LinuxMint,45,4
RedHat,12,5

Regex(,[0-9]$)检查单位,在最后的领域和p命令指纹的线这符合这一条件。

  1. 到数字中的所有行的文件:
$ sed = file | sed 'N;s/\n/ /'

1 Solaris,25,11
2 Ubuntu,31,2
3 Fedora,21,3
4 LinuxMint,45,4
5 RedHat,12,5

这是模拟猫-n命令。 awk且它容易使用特殊的可变NR。 该'='的命令sed给线路数量的每一个线随后通过的行本身。 Sed输出是通过管道输送到另一个sed命令参加每2线。

  1. 将最后一领域通过99如果第1段是'Ubuntu':
$ sed 's/\(Ubuntu\)\(,.*,\).*/\1\299/' file

Solaris,25,11
Ubuntu,31,99
Fedora,21,3
LinuxMint,45,4
RedHat,12,5

这regex匹配'Ubuntu'和直到结束,除了最后一栏和组,他们每个人。 在更换部分,第1和第2小组沿用新的编号99被取代。

  1. 删除第2段,如果第1段是'RedHat':
$ sed 's/\(RedHat,\)[^,]*\(.*\)/\1\2/' file

Solaris,25,11
Ubuntu,31,2
Fedora,21,3
LinuxMint,45,4
RedHat,,5

第1场'RedHat',第2段和剩余的领域进行分组,并更换做是只有第1次和最后一组,resuting在得到第2段删除。

  1. 插入一个新的栏在结束(最后一列):
$ sed 's/.*/&,A/' file

Solaris,25,11,A
Ubuntu,31,2,A
Fedora,21,3,A
LinuxMint,45,4,A
RedHat,12,5,A

Regex(.*) 与整个线和替换它的行本身(&)和新的领域。

  1. 插入一个新列在开始(第1栏):
$ sed 's/.*/A,&/' file

A,Solaris,25,11
A,Ubuntu,31,2
A,Fedora,21,3
A,LinuxMint,45,4
A,RedHat,12,5

同样,作为最后一个例子,只是线匹配之后是新的列

我希望这将有所帮助。 让我知道如果你需要使用Awk或任何其他命令。 谢谢你

2021-11-24 07:36:29

谢谢你的详尽解释,但遗憾的是它没有解决的问题。
Helium

其他语言

此页面有其他语言版本

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................