Удалить последние n символов из строк файла

Удалить последние n символов из строк файла

Я использую терминал Mac (bash) и у меня есть файл, data_list.txtкоторый содержит nследующие строки:

aaabbbccc_7777.txt 
nnhhaa_8888.txt 
ayquabay_9999.txt 
ayqynbnbn_1122.txt 
ooppaa_3454.txt

Как удалить последние 8 символов каждой строки?

Ожидаемый результат data_list.txt:

aaabbbccc_ 
nnhhaa_ 
ayquabay_ 
ayqynbnbn_ 
ooppaa_

Спасибо за любую помощь.

решение1

Если вы хотите удалить последние 8 символов или все символы, если их меньше 8, вы можете сделать следующее:

sed "s/.\{0,8\}$//; /^$/d" data_list.txt

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

Если вам нужно удалить все конечные пробелы (не включая их в 8 символов), вы можете сделать следующее:

sed "s/.\{0,8\}[[:space:]]*$//" data_list.txt

Я могу только догадываться, каково фактическое условие того, что следует удалить в конце (например, все после подчеркивания или число + расширение), но если вы хотите удалить расширение файла и любые цифры перед ним:

sed "s/[[:digit:]]*\..*$//" data_list.txt

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

решение2

Для вашего точного ввода (все строки на концах имеют пробелы, кроме последней строки) вы можете использовать это (я полагаю, вы хотите избавиться от «after _ part»):

sed 's/........ *$//' data_list.txt

Чтобы избавиться от всего, что находится после последнего символа «подчеркивания», используйте этот код:

sed 's/\(.*_\).*$/\1/' data_list.txt

Это также будет работать в строках, которые содержат несколько символов "подчеркивания", потому что sed "жадный". Хотя я не знаю, будет ли это работать на MacOS, по крайней мере это будет полезно для пользователей sed в Linux, которых поисковая система Google поместит сюда...

решение3

Вот awkрешение, которое столь же быстро, как и подход Фриппе sed, с использованием примера файла со 100 000 строк:

time awk '{print substr($0, 1, length($0)-8)}' 100k.txt

real    0m4.110s
user    0m0.142s
sys     0m0.422s

time sed "s/.\{0,8\}$//; /^$/d" 100k.txt

real    0m4.043s
user    0m1.558s
sys     0m0.345s

Замените 8на любое число. Главное отличие здесь в том, что awkбудет печатать новую строку, если длина обрезки превысит длину строки, а sedне будет.

решение4

Использование Raku (ранее известного как Perl_6)

raku -ne '.trim-trailing.chop(8).put;'

ИЛИ

raku -pe '.=trim-trailing; .=chop(8);'

Пример ввода:

wxxyyyzzzz_1234.txt
aaabbbccc_7777.txt 
nnhhaa_8888.txt 
ayquabay_9999.txt 
ayqynbnbn_1122.txt 
ooppaa_3454.txt

Пример вывода:

wxxyyyzzzz_
aaabbbccc_
nnhhaa_
ayquabay_
ayqynbnbn_
ooppaa_

Обратите внимание, что оба ответа выше используют процедуру Raku trim-trailingдля избавления от конечных пробелов. Не стесняйтесь удалять trim-trailingи/или корректировать количество символов chop-ped с правого конца строки.

https://docs.raku.org/routine/chop
https://raku.org

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