根据另一列的条件更改一列的值

根据另一列的条件更改一列的值

我有一系列包含 6 列的 .txt 文件,如下所示:

-44.2584 0.2603  42.7879 6 0.1 Precentral_L
49.3816  5.3947  40.4102 6 0.1 Precentral_R
-22.5897 9.5277  54.8691 6 0.1 Frontal-Sup_L
26.0365  32.0674 36.7889 6 0.1 Frontal-Sup_R

文件之间的行数是可变的。我想更改第四列 (6) 的条件:当标签为“R”时,更改为 1。是否有一个简单的命令?

答案1

$ awk '$6 ~ /_R$/ { $4 = 1 }1' input.txt 
-44.2584 0.2603  42.7879 6 0.1 Precentral_L
49.3816 5.3947 40.4102 1 0.1 Precentral_R
-22.5897 9.5277  54.8691 6 0.1 Frontal-Sup_L
26.0365 32.0674 36.7889 1 0.1 Frontal-Sup_R

当第 6 列以 结尾时_R,将列 $4 更改为1。 awk 脚本末尾的的1计算结果为 true,因此导致 awk 执行其默认操作,即print

如果您需要编辑输入文件而不仅仅是将结果打印到 stdout,并且您使用的是 GNU 版本的 awk,则可以使用 gawk 的inplace库。例如

awk -i inplace -v INPLACE_SUFFIX=.bak '$6 ~ /_R$/ { $4 = 1 }1' ./*.txt 

如果没有 GNU awk,您必须将每个输入文件的输出写入临时文件,然后将其重命名为原始文件。或者只是将输出文件写入不同的目录并保留原始文件和修改后的文件(在我看来,覆盖文件的原始副本通常是一个坏主意,除非您的磁盘空间非常不足。您可以稍后删除原始文件,但除非您有备份或快照,否则您无法取消删除它们)。例如

$ mkdir out

$ awk -v OUTDIR=./out '
    function basename(f) { sub(".*/", "", f); return f }
    $6 ~ /_R$/ { $4 = 1 }
    { print > OUTDIR "/" basename(FILENAME) }' ./*.txt

$ cat out/input.txt 
-44.2584 0.2603  42.7879 6 0.1 Precentral_L
49.3816 5.3947 40.4102 1 0.1 Precentral_R
-22.5897 9.5277  54.8691 6 0.1 Frontal-Sup_L
26.0365 32.0674 36.7889 1 0.1 Frontal-Sup_R

FILENAME是一个内置 awk 变量,包含当前正在处理的文件的名称。 awk 没有内置basename()函数,因此我必须编写一个简单的函数,仅使用 awk 的sub()函数从文件名中删除路径。重定向在 awk 中的工作方式与在 shell 中的工作方式类似。

答案2

使用sed

$ sed '/.*_R/s/\(\([^ ]* *\)\{3\}\)[0-9]/\11/' input_file
-44.2584 0.2603  42.7879 6 0.1 Precentral_L
49.3816  5.3947  40.4102 1 0.1 Precentral_R
-22.5897 9.5277  54.8691 6 0.1 Frontal-Sup_L
26.0365  32.0674 36.7889 1 0.1 Frontal-Sup_R

答案3

$ awk '/R$/{$4=1}1' file
-44.2584 0.2603  42.7879 6 0.1 Precentral_L
49.3816 5.3947 40.4102 1 0.1 Precentral_R
-22.5897 9.5277  54.8691 6 0.1 Frontal-Sup_L
26.0365 32.0674 36.7889 1 0.1 Frontal-Sup_R

$ awk '/R$/{$4=1}1' file | column -t
-44.2584  0.2603   42.7879  6  0.1  Precentral_L
49.3816   5.3947   40.4102  1  0.1  Precentral_R
-22.5897  9.5277   54.8691  6  0.1  Frontal-Sup_L
26.0365   32.0674  36.7889  1  0.1  Frontal-Sup_R

$ awk '/R$/{$4=1}1' file | column -o' ' -t
-44.2584 0.2603  42.7879 6 0.1 Precentral_L
49.3816  5.3947  40.4102 1 0.1 Precentral_R
-22.5897 9.5277  54.8691 6 0.1 Frontal-Sup_L
26.0365  32.0674 36.7889 1 0.1 Frontal-Sup_R

相关内容