在 shell 脚本中使用 sed 来替换 csv 文件中的整行而不弄乱它的正确方法是什么?

问题描述 投票:0回答:1
case $selectedField in
    fullname)
        sed -i '' "/$argname/ s/\([^,]*,\)[^,]*/\1$argnewdata/" "$filename"
        ;;
    age)
        sed -i '' "/$argname/ s/\([^,]*,[^,]*,\)[^,]*/\1$argnewdata/" "$filename"
        ;;
    country)
        sed -i '' "/$argname/ s/\([^,]*,[^,]*,[^,]*,\)[^,]*/\1$argnewdata/" "$filename"
        ;;
    status)
        sed -i '' "/$argname/ s/\([^,]*,[^,]*,[^,]*,[^,]*,\)[^,]*/\1$argnewdata/" "$filename"
        ;;
    rescued)
        sed -i '' "/$argname/ s/\([^,]*,[^,]*,[^,]*,[^,]*,[^,]*,\)[^,]*/\1$argnewdata/" "$filename"
        ;;
    record)
        if [[ $argnewdata =~  ^[0-9]+,.*,[0-9]+,.*,(Passenger|Crew),(Yes|No)$ ]]; then
            sed -i '' "/$argname/c\\
            $argnewdata" "$filename"
            #echo $argnewdata
        else
            echo "Invalid format. Please try again."
        fi
        #sed -i '' "/$argname/c$new_value" "$filename"
        #$argnewdata =~ ^[0-9]+,.*,[0-9]+,.*,(Passenger|Crew),(Yes|No)$
        ;;
    *)
        echo "Invalid field."
        return
        ;;
esac

这是我的代码,抱歉它搞砸了。 在案例记录上的案例陈述上)当我用它来替换 csv 文件时,会发生这种情况:

1312,Nikol,37,asdffe,Passenger,Yes32,Nikolas,98,jsiajsi,Passenger,Yes

问题在于它与下面的行相冲突并在开头添加了许多空格(我不知道是否显示了空格)。 我发现,如果我删除 sec c\ 命令第二行之前用于正确格式的空格,则可以修复该问题。这意味着它不仅用变量替换旧文本,而且还在其前面添加了空格。我怎样才能避免它,这样我就不必弄乱格式。另外为什么它会与下面的线相碰撞?

预计:

1312,Nikolaos,37,asdffe,Passenger,Yes
32,Nikolas,98,jsiajsi,Passenger,Yes

实际:

1312,Nikolaos,37,asdffe,Passenger,Yes32,Nikolas,98,jsiajsi,Passenger,Yes
shell sed
1个回答
0
投票

case
选项

c\
删除整行,包括换行符,因此只需添加
\n
:
sed -i '' "/$argname/c\\$argnewdata\n" "$filename"
。但
s\
可能更直接:

sed -i '' "/$argname/ s/.*/$argnewdata/" "$filename"

其他选择

要使用

fullname
选项,您需要(在命令行)传递新的全名及其后面的列。这是那行:

sed \
  -i '' \
  "/$argname/ s/\([^,]*,[^,]*,\)[^,]*/\1$argnewdata/" \
  "$filename"

对于您的所有情况都匹配此模式可能会更好:

^([^,]*),([^,]*),([^,]*),([^,]*),([^,]*)$

然后只需根据情况更改替换字符串即可。例如,对于

country
,请使用:

\1\2$newargdata\3\4\5

小事...

考虑使用

-E

sed -E
使用现代正则表达式,它更强大且可读。它不是 POSIX 但得到广泛支持。您可以使用
(
)
而不转义、
+
、命名捕获组等。
^(?<name>[^,]+)
会起作用。

(仅供参考:我认为

-i ''
仅适用于 BSD 和 macOS。)

处理类似

"john, johnson"
:

的字段

CSV 通常使用

""
包围包含
,
的字段。只要没有字段同时包含
"
,
,那么我认为这有效:

([^,]*|"[^"]*"),

使用非零返回和退出代码:

echo "Invalid format. Please try again."
exit 1

还有

    *)
        echo "Invalid field."
        return 1
        ;;
© www.soinside.com 2019 - 2024. All rights reserved.