1

I am new on coding in bash Linux and I have the following problem.

I'm trying to concatenate string in loop to create a path. I have a text file in which I stored some strings to use in the loop. I wrote this example just to show you the problem:

for bio in `cat /data/giordano/species_ranges/prova_bio.txt` # list of strings: "bio_01", "bio_02"...
do
echo  /data/giordano/species_range/$bio.tif # concatenation
done

The result I expect would be:

/data/giordano/species_range/bio_01.tif
/data/giordano/species_range/bio_02.tif
/data/giordano/species_range/bio_03.tif

But what actually came out was:

.tifa/giordano/species_range/bio_01
.tifa/giordano/species_range/bio_02
.tifa/giordano/species_range/bio_03
/data/giordano/species_range/bio_04.tif

I really don't understand what kind of problem it is...

Giordano
  • 81
  • 5
  • 1
    Looks like you have carriage return characters in your file's line endings. Did you maybe create it on Windows? – carlfriedrich Feb 20 '22 at 10:08
  • See https://askubuntu.com/questions/803162/how-to-change-windows-line-ending-to-unix-version – carlfriedrich Feb 20 '22 at 10:12
  • 2
    ["Are shell scripts sensitive to encoding and line endings?"](https://stackoverflow.com/questions/39527571/are-shell-scripts-sensitive-to-encoding-and-line-endings) has a bunch of options for dealing with Windows line endings. Also, [don't read lines with `for`](https://mywiki.wooledge.org/DontReadLinesWithFor); use a `while read` loop instead (see [BashFAQ #1](https://mywiki.wooledge.org/BashFAQ/001), and BTW `while IFS=$'\r' read ...` is one way to fix Windows line endings). Finally: use [shellcheck.net](https://www.shellcheck.net) to spot common scripting mistakes. – Gordon Davisson Feb 20 '22 at 10:37

2 Answers2

1

I suggest that awk would be simpler for this task. We use tr to remove the Cr line endings

~/tests/bash $ tr -d "\r" < data/giordano/species_range/proverbio.txt | awk '{ print "/data/giordano/species_range/" $0 ".tif"
> }'
/data/giordano/species_range/bio_1.tif
/data/giordano/species_range/bio_2.tif
/data/giordano/species_range/bio_3.tif
/data/giordano/species_range/bio_4.tif

Thank you to Charles Duffy for the improvements.

0

You probably have Windows line endings in your file, which contain an additional carriage return (\r). This makes the cursor go to the beginning of the line. You can remove the \rs from your file by piping to tr. Extend your first line like this:

for bio in `cat /data/giordano/species_ranges/prova_bio.txt | tr -d '\r'`
carlfriedrich
  • 2,919
  • 1
  • 15
  • 29
  • However, one shouldn't use `for line in $(cat file)` at all in the first place; see [DontReadLinesWithFor](https://mywiki.wooledge.org/DontReadLinesWithFor) – Charles Duffy Feb 20 '22 at 12:47
  • 1
    ...if one switches to a [BashFAQ #1](https://mywiki.wooledge.org/BashFAQ/001) `while read` loop, making it ignore `\r`s doesn't require `tr` at all: `while IFS=$'\r' read -r bio; do ...; done – Charles Duffy Feb 20 '22 at 12:49