У меня есть текстовый файл, содержащий одно имя файла в каждой строке:
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
(как указано в сценарии), вы можете использовать-n
параметр echo:Или вы можете использовать функции оболочки для обработки строки без использования
cut
:(замена обеих
echo
строк).В качестве альтернативы,
printf
тоже бы сработал, работает в любой оболочке POSIX и, как правило, лучше (см. Подробнее, почему printf лучше, чем echo? ):или
(Строго говоря, простыми словами
/bin/sh
,echo -n
он не переносимый . Так как вы явно используетеbash
, здесь все в порядке.)источник
Не делай такого рода вещи в оболочке! Это намного сложнее, чем необходимо, подвержено ошибкам и намного, намного медленнее. Есть много инструментов, предназначенных для такой обработки текста. Например, в
sed
(здесь предполагается недавняя реализация GNU или BSD для-E
):Или для любого
sed
:Perl:
AWK:
источник
sed
один вsed 's/\([^_]*\).*/& \1/' file
для дополнительной портативности. Дело в том, что вы можете рассчитыватьawk
иsed
быть там больше, чем вы можете рассчитывать почти на все остальное.А, вот и ты:
Выход:
источник