【问题标题】:Bash: delete chars in a file, only on the first lineBash:删除文件中的字符,仅在第一行
【发布时间】:2013-12-03 19:14:48
【问题描述】:

我正在制作一个脚本来将大量文件从一个路径复制到另一个路径。 路径上的任何文件在第一行都有很多“垃圾”,直到单词“Return-Path.....”

文件内容示例:

§°ç§°*é*é*§°ç§°çççççççReturn-PathOTHERTHINGS
REST
OF
THE
FILE
EOF

sed 或 awk 可能对此有所帮助。

问题:

我想要文件的全部内容,除了“Return-Path”之前的任何内容,它应该只在第一行被剥离,这样:

Return-PathOTHERTHINGS
REST
OF
THE
FILE
EOF

重要的事情:Return-Path 之前的任何内容都是“二进制”,事实上文件被视为二进制... 如何解决?

【问题讨论】:

    标签: bash sed awk


    【解决方案1】:

    好的,这是新的一天,现在我确实想为你编写代码 :-)

    该算法在我对您相同问题的其他答案中进行了描述。

    #!/bin/bash
    ################################################################################
    # behead.sh
    # Mark Setchell
    # 
    # Utility to remove stuff preceding specified string near start of binary file
    #
    # Usage: behead.sh <infile> <outfile>
    ################################################################################
    IN=$1
    OUT=$2
    SEARCH="Return-Path"
    for i in {0..80}; do
       str=$(dd if="$1" bs=1 count=${#SEARCH} iseek=$i 2> /dev/null)
       if [ "$str" == $SEARCH ]; then
          # The following line will go faster if you exchange "bs" and "iseek" 
          # parameters, because it will work in bigger blocks, it just looks
          # wrong, so I haven't done it.
          dd if="$1" of="$OUT" bs=1 iseek=$i 2> /dev/null
          exit $?
       fi
    done
    echo String not found, sorry.
    exit 1
    

    你可以像这样测试它:

    #
    # Create binary with 15 bytes of bash, then "Return-Path", then entire bash in file "bashed"
    (dd if=/bin/bash bs=1 count=15 2>/dev/null; echo -n 'Return-Path'; cat /bin/bash) > bashed
    #
    # Chop off junk at start of "bashed" and save in "restored"
    ./behead.sh bashed restored
    #
    # Check the restored "bash" is exactly 11 bytes longer than original, 
    # as it has "Return-Path" at the beginning
    ls -l bashed restored
    

    如果您将我的脚本保存为“behead.sh”,您需要像这样使其可执行:

    chmod +x behead.sh
    

    然后你可以这样运行它:

    ./behead.sh inputfile outputfile
    

    顺便说一句,二进制文件中没有“一行”的概念,所以我假设前 80 个字符 - 当然你可以随意更改它!

    【讨论】:

      【解决方案2】:

      试试:

      sed '1s/.*Return-Path/Return-Path/'
      

      此命令仅在第一行将“Return-Path”之前的任何内容替换为“Return-Path”。

      【讨论】:

      • 对不起,但我忘了指定它们是“二进制”文件,并且在那个词之前它们是“二进制”...前两行示例:IMS6^@^@^XCP`fL ^@^@^@^@^@^@^Xc^@^@^@^@^@^@^@^@^@^@^@^@Return-Path: 收到: 来自 asmtp1.website.it (122.1.53.13) by mail1.damn.com
      【解决方案3】:

      我现在不想编写此代码,但也许可以给你一个提示。 “返回路径”为 11 个字符。您可以从偏移量“n”的文件中获取 11 个字符

      dd if=file bs=1 count=11 iseek=n
      

      因此,如果您使用“n”从零开始并增加直到结果与“Return-Path”匹配,您可以计算需要从前面删除多少字节。然后你可以用另一个“dd”来做到这一点。

      或者,看看通过“xxd”运行文件,用“sed”编辑它,然后用“xxd -r”通过“xxd”运行它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-08
        • 1970-01-01
        相关资源
        最近更新 更多