简体   繁体   中英

keep the delimiter '\t' after running awk command to remove the last column

I found the following command to remove the last column from a file

awk 'NF{NF-=1};1' <in >out

the command is copied from here. https://unix.stackexchange.com/questions/234432/how-to-delete-the-last-column-of-a-file-in-linux?newreg=b1ebf81f0ea5458eafc3370a6739b1a9

Here comes the problem. The file was originally separated by '\\t', after this command, the delimiter is no longer '\\t'. Anyone knows the reason? and how to keep the delimiter?

You have to define the output separator:

awk 'BEGIN{FS=OFS="\t"}NF{NF-=1};1' input > output

remark: redefining the variable NF is undefined behaviour by POSIX but it is allowed in GNU awk and a few other versions of awk.

The following will work very well with any awk:

awk 'BEGIN{FS="\t"}{sub(FS "[^"FS"]*$","")}1' input > output

knows two concepts very well:

  • records : a file is split in records where each record is separated from another record by the record separator RS . By default this is the <newline> character and thus records are lines.
  • fields : a record is split in fields where each field is separated from another field by the field separator FS . By default, this is any sequence of blanks (spaces and tabs).

Obviously, if you can define how the input is build up by defining its record separtor RS and field separtor FS , you can also tell awk how the output is build up. Hence, you can define the output record separtor ORS which is appended after each printed record when you use the print statement. And next to ORS you can define the output field separator OFS which tells awk how fields are split. Each , -operator in the print statement is normally replaced by a OFS , eg:

print field1, field2, field3

will print

field 1 OFS field2 OFS field3 ORS

The complete record $0 will also be redefined as a string with OFS when you change a field or remove some fields.

Another solution might be to use rev and cut :

rev input | cut -f2- | rev > output
awk '{sub(/\t[^\t]*$/,"")}1' file

以上将适用于任何awk。

Here are a few alternate solutions which should hopefully give you something to choose from.

perl -pe 's/\t[^\t]*$//' file
sed -e $'s/\t[^\t]*$//' file  # Bash C-style $'string'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM