Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macos 使用sed命令从多个文件中删除行_Macos_Bash_Shell_Sed_Zsh - Fatal编程技术网

Macos 使用sed命令从多个文件中删除行

Macos 使用sed命令从多个文件中删除行,macos,bash,shell,sed,zsh,Macos,Bash,Shell,Sed,Zsh,所以,免责声明:我对使用bash和zsh非常陌生,所以答案可能非常简单。尽管如此我查看了以前的帖子,没有找到任何东西。(编辑:我在bash和zsh shell中都尝试过这一点-同样的问题。) 我有一个包含许多文件的目录,正在尝试从每个文件中删除第一行 假设目录包含:file1.txt file2.txt file3.txt。。。等等 我正在使用sed命令(非GNU): 出于某种原因,这只是删除第一个文件的第一行。我认为*.txt会影响目录中与模式匹配的所有文件。奇怪的是,它正在创建附加了-e的文

所以,免责声明:我对使用bash和zsh非常陌生,所以答案可能非常简单。尽管如此我查看了以前的帖子,没有找到任何东西。(编辑:我在bash和zsh shell中都尝试过这一点-同样的问题。)

我有一个包含许多文件的目录,正在尝试从每个文件中删除第一行

假设目录包含:file1.txt file2.txt file3.txt。。。等等

我正在使用sed命令(非GNU):

出于某种原因,这只是删除第一个文件的第一行。我认为*.txt会影响目录中与模式匹配的所有文件。奇怪的是,它正在创建附加了-e的文件副本,但副本和原始文件都是相同的

我用其他命令(例如ls*.txt)试过了,效果很好。我有什么遗漏的吗

先谢谢你

  • 不用-e就可以使用它 对于一个文件使用:

    sed -i '1d' filename
    
    对于所有文件,请使用:

    sed -i '1d' *.txt
    

    .对我来说,我使用的是ubuntu和debian系统,这种方法100%适用于我,但对于其他平台,我不确定,所以这是另一种方法:

  • 用emty模式替换第一行,并删除空行(双命令):

    对于$格式的文件(ls/path/to/files/*.txt);do sed-i“s/$(head-1“$files”)//g“$files”;sed-i'/^$/d'$files”;完成

  • 注意:如果您的文件包含splash“/”,那么它将给出错误,因此在本例中,sed命令应该如下所示(
    sed-i“s[$(head-1“$files”)[[g”


    希望这就是您想要的:)

    不同操作系统中不同版本的
    sed
    支持不同的参数

    OpenBSD(5.4)sed
    -i
    标志不可用。您可以使用以下
    /bin/sh
    语法:

    for i in *.txt
    do
        f=`mktemp -p .` 
        sed -e "1d" "${i}" > "${f}" && mv -- "${f}" "${i}"
    done
    
    FreeBSD(11电流)sed
    -i
    标志需要一个扩展名,即使它是空的。因此必须写成
    sed-i”“-e“1d”*.txt

    逗号分隔符 这将查看
    -i
    后面的参数是否是另一个选项(或可能是一个命令)。如果是,则假定进行了就地修改。如果它是一个文件扩展名,如“
    .bak
    ”,则会将原始文件重命名为“
    .bak
    ”,然后将其修改为原始文件的名称


    在其他平台上可能还有其他变体,但我手头有三个。

    这里的问题是,sed打开新文件时,行号不会重置,因此
    1
    仅与第一个文件的第一行匹配

    一种解决方案是使用shell循环,为每个文件调用一次sed。演示了如何以最广泛兼容的方式执行此操作,尽管如果您有支持
    -i
    标志的sed版本,您可以改为:

    for i in *.txt; do
        sed -i.bak '1d' "$i"
    done
    
    通过传递一个空后缀可以避免创建备份文件,但就我个人而言,我并不认为这是一件坏事。总有一天你会感激它的


    似乎您没有使用GNU工具,但如果您使用GNU工具,我建议您使用GNU awk来完成此任务。变量
    FNR
    在这里很有用,因为它可以单独跟踪每个文件的记录编号,允许您执行以下操作:

    gawk -i inplace 'FNR>1' *.txt
    
    使用
    inplace
    扩展名,只需打印
    FNR
    大于1的行,即可从每个文件中删除第一行

    测试它:

    $ seq 5 > file1
    $ seq 5 > file2
    $ gawk -i inplace 'FNR>1' file1 file2
    $ cat file1
    2
    3
    4
    5
    $ cat file2
    2
    3
    4
    5
    

    您要传递给Sed的最后一个论点是问题 试试这样的

    var=(`find *txt`)
    for file in "${var[@]}"
    do
        sed -i -e 1d $file
    done
    

    这对我起到了作用。

    你使用的是bash还是zsh?我的印象是几乎没有什么不同(至少对我的初学者来说)。目前我使用的是zsh。谢谢你的回复。我已经使用了BSD sed,所以我必须为“-I”提供一些扩展,否则我会出错。即使我尝试添加-I'',也会发生同样的情况。我不是一个很好的linuxer,但我会在这个答案中添加更多命令,希望能有所帮助。太好了!非常感谢你,Younes。现在一切都解决了。我只会在文本中添加POSIX版本(taht是OpenBSD版本)。并尽量在sed操作中使用简单的引号(避免任何shell解释)。非常感谢您花时间对此做出回应,Gumnos。您对for循环的建议非常有效。干杯!更新此答案:OpenBSD最新版本中的
    sed
    现在以与FreeBSD相同的方式支持
    -i
    标志。谢谢您,Tom。我一定会考虑在未来的ta中使用awksks。(在看了一些文档之后,它看起来非常强大——尽管学习曲线很陡)。我也会研究GNU的实现。再次感谢,伙计。干杯。太好了!这非常有效。感谢你花时间回答这个问题!
    $ seq 5 > file1
    $ seq 5 > file2
    $ gawk -i inplace 'FNR>1' file1 file2
    $ cat file1
    2
    3
    4
    5
    $ cat file2
    2
    3
    4
    5
    
    var=(`find *txt`)
    for file in "${var[@]}"
    do
        sed -i -e 1d $file
    done