Как удалить \n между выводами двух команд echo?

Как удалить \n между выводами двух команд echo?

У меня есть текстовый файл, содержащий одно имя файла в каждой строке:

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

Я хочу преобразовать его в такую ​​форму:

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

используя этот код:

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

но результат таков:

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

Как мне изменить свой сценарий, чтобы получить желаемое на выходе?

решение1

Не делайте такого рода вещи в оболочке! Это гораздо сложнее, чем необходимо, подвержено ошибкам и гораздо, гораздо, медленнее. Существует множество инструментов, предназначенных для таких текстовых манипуляций. Например, в sed(здесь предполагается недавняя реализация GNU или BSD для -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

Или, для любого 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 -pe 's/(.+?)_.*/$& $1/' file
111_c4l5r120.png 111
123_c4l4r60.png 123
135_c4l4r180.png 135
147_c4l3r60.png 147
15_c4l1r120.png 15

awk:

$ 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

решение2

Если у вас нет особой необходимости использовать оболочку для этого,ответ тердонапредоставляет лучшие альтернативы.

Поскольку вы используете bash(как указано в скрипте), вы можете использовать -nопцию echo:

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

Или вы можете использовать функции оболочки для обработки строки без использования cut:

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

(замена обеих echoстрок).

В качестве альтернативы, printfтоже подойдет, работает в любомОболочка POSIX, и в целом лучше (см.Почему printf лучше, чем echo?для получения подробной информации):

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

или

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

(Строго говоря, на простом языке /bin/sh,echo -nне является портативным. Поскольку вы явно используете bashего, здесь все в порядке.)

решение3

Вот, пожалуйста:

#!/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"

Выход:

$ 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

Связанный контент