批处理替换.csv文件中特定字符串的shell脚本

z2acfund  于 12个月前  发布在  Shell
关注(0)|答案(4)|浏览(134)

我想取代我的原始CSV文件中的一些字符串,以供进一步使用,我搜索互联网和创建脚本到目前为止。但似乎它们不起作用。希望有人能帮助我
csv文件是这样的,我想删除“^M”和“#列:“这样我就能看我的档案了

# Task: bending1^M
# Frequency (Hz): 20^M
# Clock (millisecond): 250^M
# Duration (seconds): 120^M
# Columns: time,avg_rss12,var_rss12,avg_rss13,var_rss13,avg_rss23,var_rss23^M
#!/usr/bin/env bash
function scandir(){
cd `dirname $0`
echo `pwd`
local cur_dir parent_dir workir
workdir=$1
cd ${workdir}

if [ ${workdir}="/" ]
then 
    cur_dir=""
else
    cur_dir=$(pwd)
fi

for dirlist in $(ls ${cur_dir})
do
    if test -d ${dirlist}
    then
        cd ${dirlist}
        scandir ${cur_dir}/${dirlist}
        cd ..
    else
        vi ${cur_dir}/${dirlist} << EOF
        :%s/\r//g
        :%s/\#\ Columns:\ //g
        :wq
        EOF
    fi
done
}
v1l68za4

v1l68za41#

你的整个脚本看起来就像:

find "$workdir" -type f | xargs -n1 sed -i -e 's/\r//g; s/^# Columns://'

注意你的脚本:

  • 检查脚本在https://www.shellcheck.net/上的有效性
  • 此处的<< EOF文档无效。结束词EOF * 必须 * 从脚本中的行首开始:
vi ${cur_dir}/${dirlist} << EOF
    :%s/\r//g
    :%s/\#\ Columns:\ //g
    :wq
EOF
#^^ no spaces in front of EOF, also no spaces/tabs after EOF
# the whole line needs to be exactly 'EOF'

不能有任何空格,制表符在它的前面。此外,我不认为vi不是在文件上运行替换的最佳工具,我也不知道它如何处理:前面的制表符或空格。您可能想尝试在:前面没有空格字符的情况下运行它:

vi ${cur_dir}/${dirlist} << EOF
:%s/\r//g
:%s/\#\ Columns:\ //g
:wq
EOF
  • 反引号是deprecated,可读性较差,不允许简单的嵌套。使用$( ... )命令替代。
  • echo pwd只是echo的无效使用,只需使用pwd
  • for dirlist in $(lsparsing ls output is bad。使用find命令代替,或者如果必须的话,shell globulation,即。for dirlist in *
  • if [ ${workdir}="/" ]无效。这测试字符串"${workdir}=/是否不为null。Bash是空间感知的,它需要在=和操作数之间有一个空格。应该是if [ "${workdir}" = "/" ]
  • Always quote your variables。不要cd ${dirlist}cd "${dirlist}"等等。
aij0ehis

aij0ehis2#

好张贴的答案是正确的,但我会推荐这种语法:

find "$1" -type f -name '*.csv' -exec sed -e 's/\r$//;s/^# Columns: //' -i~ {} +
  • 在find命令的末尾使用+而不是\;将允许sed一次处理许多文件,减少分叉并使整个作业更快。
  • -i后的~选项将重命名现有文件,方法是在名称末尾附加波浪号,而不是删除它们。
  • 使用-type f将确保只处理文件(没有符号链接,目录,套接字,FIFO,设备...)
hm2xizp9

hm2xizp93#

您可以将整个脚本缩减为一个命令,并且不必使用Vim来处理文件:

find ${workdir} -name '*.csv' -exec sed -i -e 's/\r$//; /^#/d' '{}' \;

说明:

  • find <dir> -name <pattern> -exec <command> \;将在每个文件上搜索<dir> for files matchingand execute `。你想搜索CSV文件并对它们执行一些操作(对它们运行命令)。
  • 在找到的每个(CSV)文件上运行的命令将是sed -i -e 's/\r$//; /^#/d'。这意味着就地编辑文件(-i)并对它们运行两个转换。s/\r$//将删除每行中的^M/^#/d将删除所有以#开头的行。
  • '{}'find找到的文件替换,\;标记find运行的命令结束(参见find手册页)。

大多数脚本都模拟find命令的一部分。这不是个好主意
此外,对于简单的文本处理,使用sed而不是调用诸如Vim之类的编辑器更容易、更快。

ojsjcaue

ojsjcaue4#

对我来说,这是可行的:
我想用“something”代替“some string”。所以我使用这个命令来替换csv文件中的文本。

sed -i '' 's/old string/new string/g' data.csv

相关问题