Como remover \n entre as saídas de dois comandos echo?

Como remover \n entre as saídas de dois comandos echo?

Eu tenho um arquivo de texto contendo um nome de arquivo em cada linha:

111_c4l5r120.png
123_c4l4r60.png
135_c4l4r180.png
147_c4l3r60.png
15_c4l1r120.png
...

Quero convertê-lo nesta forma:

111_c4l5r120.png 111
123_c4l4r60.png 123
135_c4l4r180.png 135
147_c4l3r60.png 147
15_c4l1r120.png 15
...

usando este código:

#!/bin/bash
while IFS='' read -r line || [[  -n "$line"  ]]; do
   echo "$line" >> output.txt   
   echo "$line" | cut -d'_' -f 1 >> output.txt
done < "$1"

mas o resultado é:

111_c4l5r120.png 
111
123_c4l4r60.png 
123
135_c4l4r180.png 
135
147_c4l3r60.png 
147
15_c4l1r120.png 
15
...

Como devo alterar meu script para obter a saída desejada?

Responder1

Não faça esse tipo de coisa na casca! É muito mais complexo do que o necessário, sujeito a erros e muito, muito mais lento. Existem muitas ferramentas projetadas para essa manipulação de texto. Por exemplo, em sed(aqui assumindo implementações recentes de GNU ou BSD para -E):

$ sed -E 's/([^_]*).*/& \1/' file
111_c4l5r120.png 111
123_c4l4r60.png 123
135_c4l4r180.png 135
147_c4l3r60.png 147
15_c4l1r120.png 15

Ou, para qualquer sed:

$ sed 's/\([^_]*\).*/& \1/' file
111_c4l5r120.png 111
123_c4l4r60.png 123
135_c4l4r180.png 135
147_c4l3r60.png 147
15_c4l1r120.png 15

Perl:

$ perl -pe 's/(.+?)_.*/$& $1/' file
111_c4l5r120.png 111
123_c4l4r60.png 123
135_c4l4r180.png 135
147_c4l3r60.png 147
15_c4l1r120.png 15

estranho:

$ awk -F_ '{print $0,$1}' file
111_c4l5r120.png 111
123_c4l4r60.png 123
135_c4l4r180.png 135
147_c4l3r60.png 147
15_c4l1r120.png 15

Responder2

A menos que você tenha uma necessidade específica de usar o shell para isso,resposta de Terdonoferece melhores alternativas.

Como você está usando bash(conforme indicado no shebang do script), você pode usar a -nopção de ecoar:

echo -n "${line} " >> output.txt
echo "$line" | cut -d'_' -f 1 >> output.txt

Ou você pode usar recursos do shell para processar a linha sem usar cut:

echo "${line} ${line%%_*}" >> output.txt

(substituindo ambas echoas linhas).

Alternativamente, printftambém funcionaria, funciona em qualquerConcha POSIX, e geralmente é melhor (vejaPor que printf é melhor que echo?para detalhes):

printf "%s " "${line}" >> output.txt
echo "$line" | cut -d'_' -f 1 >> output.txt

ou

printf "%s %s\n" "${line}" "${line%%_*}" >> output.txt

(Estritamente falando, em termos simples /bin/sh,echo -nnão é portátil. Como você está usando explicitamente, bashtudo bem aqui.)

Responder3

Olha Você aqui:

#!/bin/bash

while IFS='' read -r line || [[  -n "$line"  ]]; do
   echo "$line" `echo "$line" | cut -d'_' -f 1` >> output.txt
#   echo "$line" | cut -d'_' -f 1 >> output.txt
done < "$1"

Saída:

$ rm -rf output.txt
$ ./test.sh 1.1; cat output.txt
111_c4l5r120.png 111
123_c4l4r60.png 123
135_c4l4r180.png 135
147_c4l3r60.png 147
15_c4l1r120.png 15

informação relacionada