Home > Back-end >  splitting a string with the "tr" command doesn't appear to work
splitting a string with the "tr" command doesn't appear to work

Time:09-16

I am trying to use the tr command to split by the tab character. It doesn't look like it is working:

#!/bin/bash

IFS=""

for l in `cat gift.txt`
do
  arr=($(echo $l | tr "\t" " "))
  echo ${arr[1]}
done

the gift.txt content:

4014    apple
4015    book
4016    candy
4017    suger

The script doesn't print anything!

CodePudding user response:

I used a while loop, as I normally use it myself and assumed that you want to read each line and then replace tab with single space.

-bash-4.2$ cat script.sh 
#!/bin/bash

while IFS= read -r line
do
        echo "$line"
        arr=$(echo "$line" | tr "       " " ")
        echo "$arr"
done < gift.txt
-bash-4.2$ cat gift.txt 
4014    apple
4015    book
4016    candy
4017    suger
-bash-4.2$ ./script.sh 
4014    apple
4014 apple
4015    book
4015 book
4016    candy
4016 candy
4017    suger
4017 suger

Adding another snippet including an array, as it was originally used in the question.

-bash-4.2$ cat gift.txt 
4014    apple
4015    book
4016    candy
4017    suger
-bash-4.2$ cat script.sh 
#!/bin/bash

declare -a arr=()

while IFS= read -r line
do
        #echo "$line"
        arr =$(echo "$line" | tr "\t" " ")
        arr ="|"
done < gift.txt

for i in "${arr[@]}"
do
        echo $i | awk -F"|" '{print $1"\n"$2"\n"$3"\n"$4}'
done
-bash-4.2$ ./script.sh 
4014 apple
4015 book
4016 candy
4017 suger

CodePudding user response:

it's a lot more straight-forward :

`gawk/mawk/mawk2 'BEGIN{FS="^$"} gsub(/\011/," ") 1'`

that's all u need.

the 1 at the end is to still print out the rows as is if no substitutes were made. if u only need the modified rows, then feel free get rid of that 1. if ur files are small enough (like less than 500MB), just

[g/m/n]awk 'gsub(/\011/," ") 1'

it's a great use-case of awk. The standard braces print statement are completely optional here, since we're leveraging the modified instance counter returned by gsub as the input for the test-conditional, which defaults to a print action if it's true.

so simply a gsub statement more than suffices.

*ps i meant as in skip the bash array or loop and send it through in one shot.

  • Related