1

I'm trying to read file line by line in bash.

Every line has format as follows text|number.

I want to produce file with format as follows text,text,text etc. so new file would have just text from previous file separated by comma.

Here is what I've tried and couldn't get it to work :

FILENAME=$1

OLD_IFS=$IFSddd
IFS=$'\n'
i=0
for line in $(cat "$FILENAME"); do
    array=(`echo $line | sed -e 's/|/,/g'`)
    echo ${array[0]}
    i=i+1;
done
IFS=$OLD_IFS

But this prints both text and number but in different format text number

here is sample input :

dsadadq-2321dsad-dasdas|4212
dsadadq-2321dsad-d22as|4322

here is sample output:

dsadadq-2321dsad-dasdas,dsadadq-2321dsad-d22as

What did I do wrong?

4 Answers 4

1

Not pure bash, but you could do this in awk:

awk -F'|' 'NR>1{printf(",")} {printf("%s",$1)}'

Alternately, in pure bash and without having to strip the final comma:

#/bin/bash

# You can get your input from somewhere else if you like. Even stdin to the script.
input=$'dsadadq-2321dsad-dasdas|4212\ndsadadq-2321dsad-d22as|4322\n'

# Output should be reset to empty, for safety.
output=""

# Step through our input.  (I don't know your column names.)
while IFS='|' read left right; do
  # Only add a field if it exists.  Salt to taste.
  if [[ -n "$left" ]]; then
    # Append data to output string
    output="${output:+$output,}$left"
  fi
done <<< "$input"

echo "$output"
Sign up to request clarification or add additional context in comments.

Comments

1

No need for arrays and sed:

while IFS='' read line ; do
    echo -n "${line%|*}",
done < "$FILENAME"

You just have to remove the last comma :-)

1 Comment

How would you remove the last comma? The first thing that comes to mind is sed....
1

Using sed:

$ sed ':a;N;$!ba;s/|[0-9]*\n*/,/g;s/,$//' file
dsadadq-2321dsad-dasdas,dsadadq-2321dsad-d22as

Alternatively, here is a bit more readable sed with tr:

$ sed 's/|.*$/,/g' file | tr -d '\n' | sed 's/,$//'
dsadadq-2321dsad-dasdas,dsadadq-2321dsad-d22as

Comments

0

Choroba has the best answer (imho) except that it does not handle blank lines and it adds a trailing comma. Also, mucking with IFS is unnecessary. This is a modification of his answer that solves those problems:

while read line ; do
    if [ -n "$line" ]; then
        if [ -n "$afterfirst" ]; then echo -n ,; fi
        afterfirst=1
        echo -n "${line%|*}"
    fi
done < "$FILENAME"

The first if is just to filter out blank lines. The second if and the $afterfirst stuff is just to prevent the extra comma. It echos a comma before every entry except the first one. ${line%|\*} is a bash parameter notation that deletes the end of a paramerter if it matches some expression. line is the paramter, % is the symbol that indicates a trailing pattern should be deleted, and |* is the pattern to delete.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.