'sed: no input files' 在循环中使用 sed -i 时

'sed: no input files' when using sed -i in a loop

我在其他问题中检查了一些解决方案,但它们不适用于我的情况,我被卡住了,所以我们开始吧。 我有一个 csv 文件,我想将其全部转换为大写。必须带一个循环,最少占用7行代码。我必须使用此命令 运行 脚本:

./c_bash.sh student-mat.csv

所以我尝试了这个脚本:

#!/bin/bash
declare -i c=0
while read -r line; do 
    if [ "$c" -gt '0' ]; then 
       sed -e 's/\(.*\)/\U/'      
    else
        echo "$line"
    fi
    ((c++))
done < student-mat.csv

我知道它上面可能有一些不必要的东西,但我想关注 sed 命令,因为它看起来像这里的问题。 该脚本显示此输出:(前 5 行):

school,sex,age,address,famsize,Pstatus,Medu,Fedu,Mjob,Fjob,reason,guardian,traveltime,studytime,failures,schoolsup,famsup,paid,activities,nursery,higher,internet,romantic,famrel,freetime,goout,Dalc,Walc,health,absences,G1,G2,G3
GP,F,17,U,GT3,T,1,1,AT_HOME,OTHER,COURSE,FATHER,1,2,0,NO,YES,NO,NO,NO,YES,YES,NO,5,3,3,1,1,3,4,5,5,6
GP,F,15,U,LE3,T,1,1,AT_HOME,OTHER,OTHER,MOTHER,1,2,3,YES,NO,YES,NO,YES,YES,YES,NO,4,3,2,2,3,3,10,7,8,10
GP,F,15,U,GT3,T,4,2,HEALTH,SERVICES,HOME,MOTHER,1,3,0,NO,YES,YES,YES,YES,YES,YES,YES,3,2,2,1,1,5,2,15,14,15
GP,F,16,U,GT3,T,3,3,OTHER,OTHER,HOME,FATHER,1,2,0,NO,YES,YES,NO,YES,YES,NO,NO,4,3,2,1,2,5,4,6,10,10
GP,M,16,U,LE3,T,4,3,SERVICES,OTHER,REPUTATION,MOTHER,1,2,0,NO,YES,YES,YES,YES,YES,YES,NO,5,4,2,1,2,5,10,15,15,15

既然我看到它有效,我想将该 sed 命令永久应用到 csv 文件,所以我在它后面放了 -i:

#!/bin/bash
declare -i c=0
while read -r line; do 
    if [ "$c" -gt '0' ]; then 
       sed -i -e 's/\(.*\)/\U/'      
    else
        echo "$line"
    fi
    ((c++))
done < student-mat.csv

但是输出并没有应用更改,而是显示如下:(前 5 行)

school,sex,age,address,famsize,Pstatus,Medu,Fedu,Mjob,Fjob,reason,guardian,traveltime,studytime,failures,schoolsup,famsup,paid,activities,nursery,higher,internet,romantic,famrel,freetime,goout,Dalc,Walc,health,absences,G1,G2,G3
sed: no input files
sed: no input files
sed: no input files
sed: no input files
sed: no input files

所以在网上查了很多不同的方案,我也试过把单引号改成双引号。

#!/bin/bash
declare -i c=0
while read -r line; do 
    if [ "$c" -gt '0' ]; then 
       sed -i -e "s/\(.*\)/\U/"       
    else
        echo "$line"
    fi
    ((c++))
done < student-mat.csv

但在这种情况下,它不会应用更改,而是生成一个 0 字节的文件。所以当我这样做时没有输出:

cat student-mat.csv

我预期的解决方案是,当我应用此脚本时,它会将所有数据永久更改为大写。应用脚本后,它应该使用命令 cat student-mat.csv: (first 5 lines)

显示
school,sex,age,address,famsize,Pstatus,Medu,Fedu,Mjob,Fjob,reason,guardian,traveltime,studytime,failures,schoolsup,famsup,paid,activities,nursery,higher,internet,romantic,famrel,freetime,goout,Dalc,Walc,health,absences,G1,G2,G3
GP,F,17,U,GT3,T,1,1,AT_HOME,OTHER,COURSE,FATHER,1,2,0,NO,YES,NO,NO,NO,YES,YES,NO,5,3,3,1,1,3,4,5,5,6
GP,F,15,U,LE3,T,1,1,AT_HOME,OTHER,OTHER,MOTHER,1,2,3,YES,NO,YES,NO,YES,YES,YES,NO,4,3,2,2,3,3,10,7,8,10
GP,F,15,U,GT3,T,4,2,HEALTH,SERVICES,HOME,MOTHER,1,3,0,NO,YES,YES,YES,YES,YES,YES,YES,3,2,2,1,1,5,2,15,14,15
GP,F,16,U,GT3,T,3,3,OTHER,OTHER,HOME,FATHER,1,2,0,NO,YES,YES,NO,YES,YES,NO,NO,4,3,2,1,2,5,4,6,10,10
GP,M,16,U,LE3,T,4,3,SERVICES,OTHER,REPUTATION,MOTHER,1,2,0,NO,YES,YES,YES,YES,YES,YES,NO,5,4,2,1,2,5,10,15,15,15

谢谢你帮助我。

Sed 工作于文件,而不是行。不要读取行,对文件使用 sed。 Sed 可以自己排除第一行。请参阅 sed 手册。

你想要:

sed -i -e '2,$s/\(.*\)/\U/' student-mat.csv

您可以使用 s/.*/\U&/ 缩短时间。


您的代码无法正常工作。请注意,您的代码 从输出中删除了第二行 。您的代码:

  • read -r line
  • 读取第一行
  • echo "$line" 打印第一行
  • c++递增
  • read -r line 读取第二行
  • 然后 sed 处理文件的其余部分(从第 3 行到最后)并以大写形式打印它们
  • 然后c++递增
  • 然后read -r line失败,循环退出