Показать все поля кроме последнего

У меня есть файл, как показано ниже

1.2.3.4.ask
sanma.nam.sam
c.d.b.test

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

Кто-нибудь может мне помочь с awk или же sed чтобы найти решение. Я не могу использовать perl Вот.

4 ответа

Оба эти sed а также awk решения работают независимо от количества полей.

С помощью sed:

$ sed -r 's/(.*)\..*/\1/' file
1.2.3.4
sanma.nam
c.d.b

Замечания: -r это флаг для расширенного регулярного выражения, это может быть -E так что посоветуйтесь с man sed, Если ваша версия sed нет флага для этого, тогда просто уберите скобки:

sed 's/\(.*\)\..*/\1/' file
1.2.3.4
sanma.nam
c.d.b

sed Решение делает жадный матч до последнего . и захватывая все перед ним, он заменяет всю строку только соответствующей частью (n-1 поля). Использовать -i вариант, если вы хотите, чтобы изменения были сохранены обратно в файлы.

С помощью awk:

$ awk 'BEGIN{FS=OFS="."}{NF--; print}' file
1.2.3.4
sanma.nam
c.d.b

awk Решение просто печатает n-1 поля, чтобы сохранить изменения обратно в файл, используйте перенаправление:

$ awk 'BEGIN{FS=OFS="."}{NF--; print}' file > tmp && mv tmp file

Реверс, вырезать, реверс обратно.

rev file | cut -d. -f2- | rev >newfile

Или заменить от последней точки до нуля:

sed 's/\.[^.]*$//' file >newfile

Регулярное выражение [^.] соответствует одному символу, который не является точкой (или переводом строки). Вам нужно исключить точку, потому что оператор повторения * "жадный"; он выберет самый левый, самый длинный из возможных совпадений.

С cut на перевернутой строке

cat youFile | rev |cut -d "." -f 2- | rev

Если вы хотите сохранить "." используйте ниже:

awk '{gsub(/[^\.]*$/,"");print}' your_file
Другие вопросы по тегам