Problem with Bash output redirection

前端 未结 11 1932
梦毁少年i
梦毁少年i 2020-12-06 06:19

I was trying to remove all the lines of a file except the last line but the following command did not work, although file.txt is not empty.

$cat file.txt |ta         


        
11条回答
  •  陌清茗
    陌清茗 (楼主)
    2020-12-06 07:11

    This works nicely in a Linux shell:

    replace_with_filter() {
      local filename="$1"; shift
      local dd_output byte_count filter_status dd_status
      dd_output=$("$@" <"$filename" | dd conv=notrunc of="$filename" 2>&1; echo "${PIPESTATUS[@]}")
      { read; read; read -r byte_count _; read filter_status dd_status; } <<<"$dd_output"
      (( filter_status > 0 )) && return "$filter_status"
      (( dd_status > 0 )) && return "$dd_status"
      dd bs=1 seek="$byte_count" if=/dev/null of="$filename"
    }
    
    replace_with_filter file.txt tail -1
    

    dd's "notrunc" option is used to write the filtered contents back, in place, while dd is needed again (with a byte count) to actually truncate the file. If the new file size is greater or equal to the old file size, the second dd invocation is not necessary.

    The advantages of this over a file copy method are: 1) no additional disk space necessary, 2) faster performance on large files, and 3) pure shell (other than dd).

提交回复
热议问题