10

I want to remove all non-english alphanumerals from a file.

tr -sc '[:alnum:][:punct:]' ' ' <file

gawk and sed have the -i flag but I cannot find anything similar in the tr man pages.

How can I do this inplace, that is, store the output in the input file itself?

Stephen Kitt
  • 411,918
  • 54
  • 1,065
  • 1,164

2 Answers2

7

No. Very few commands have this functionality, GNU awk (gawk) only added it recently, and even for those commands that have an -i or equivalent, all it does is create a temp file in the background.

So, the way to do this is:

tr -sc '[:alnum:][:punct:]' ' ' <file >newfile && mv newfile file

You could whip up a little function if you need this often:

tri(){
  tmpFile=$(mktemp)
  echo "$@"
  case $# in
    ## You've given tr options
    4)
      trOpts="$1"
      set1="$2"
      set2="$3"
      inputFile="$4"
      ;;
    ## No options, only set1 and set2 and the input file
    3)
      set1="$1"
      set2="$2"
      inputFile="$3"
     ;;
    ## Something wrong
    *)
      echo "Whaaaa?"
      exit 1
      ;;
  esac
  tr "$trOpts" "$set1" "$set2" < "$inputFile" > "$tmpFile" &&
    mv "$tmpFile" "$inputFile"
}

You'd then run this as:

tri -sc '[:alnum:][:punct:]' ' ' file

Note how, unlike the real tr, this expects the file name as an argument and not as redirected input (<file), and that options be specified together as shown above (and not like -s -c).

dessert
  • 1,687
  • 14
  • 29
terdon
  • 234,489
  • 66
  • 447
  • 667
2

As that tr command always writes at most as much data as it reads, it should be safe for it to write its output in place:

With the ksh93 shell:

tr -sc '\n[:alnum:][:punct:]' '[ *]' < file 1<>; file

(here converted to standard/POSIX syntax [ *] and adding newline to the list of characters to be preserved to avoid creating non-text output).

The 1<>; ksh93-specific operator is like the standard 1<> read+write-without-truncation one except that upon successful completion of the command being redirected, the file is truncated at the current position.

Stephen Kitt
  • 411,918
  • 54
  • 1,065
  • 1,164
Stéphane Chazelas
  • 522,931
  • 91
  • 1,010
  • 1,501
  • I am sorry, I am not familiar with the ksh93 shell. Will `tr -sc '\n[:alnum:][:punct:]' '[ *]' < file` work on bash? –  Aug 21 '19 at 12:20