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

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

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 ... 

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

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

Поскольку вы используете bash (как указано в shebang скрипта), вы можете использовать параметр -n для эха:

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

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

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

(заменяя обе echo линии).

Кроме того, printf тоже будет делать трюк, работает в любой оболочке POSIX и, как правило, лучше (см. Раздел «Почему printf лучше, чем эхо?» ):

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

или

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

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

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

 $ 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 

Вот ты где:

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