Без использования sed
или awk
, только cut
, как мне получить последнее поле, когда количество полей неизвестно или изменяется с каждой строкой?
Как найти последнее поле, используя 'cut'
Ответ 1
Вы можете попробовать что-то вроде этого:
echo 'maps.google.com' | rev | cut -d'.' -f 1 | rev
Объяснение
- maps.google.com reverse будет
moc.elgoog.spam
-
cut
использует точку в качестве разделителя и выбирает первое поле, котороеmoc
- Наконец, мы снова отменим его (спасибо за напоминание, @tom), чтобы получить
com
Ответ 2
Используйте расширение параметра. Это намного эффективнее любой внешней команды, включая cut
(или grep
).
data=foo,bar,baz,qux
last=${data##*,}
См. BashFAQ # 100 для ознакомления с встроенной обработкой строк в bash.
Ответ 3
Невозможно использовать только cut
. Ниже приведен пример использования grep
:
grep -o '[^,]*$'
Замените запятую для других разделителей.
Ответ 4
Без awk?... Но это так просто с awk:
echo 'maps.google.com' | awk -F. '{print $NF}'
AWK - намного более мощный инструмент, чтобы иметь в своем кармане. -F if для разделителя полей NF - количество полей (также обозначает индекс последнего)
Ответ 5
Существует несколько способов. Вы также можете использовать это.
echo "Your string here"| tr ' ' '\n' | tail -n1
> here
Очевидно, что пустой пробел для команды tr должен быть заменен разделителем, который вам нужен.
Ответ 6
Это единственное решение, которое можно использовать только для вырезания:
echo "s.t.r.i.n.g." | cut -d '.' -F2- [repeat_follow_part_forever_or_until_out_of_memory:] | cut -d '.' -f2 -
Используя это решение, количество полей действительно может быть неизвестным и время от времени меняться. Однако, поскольку длина строки не должна превышать символы LINE_MAX или поля, включая символ новой строки, то произвольное количество полей никогда не может быть частью реального условия этого решения.
Да, очень глупое решение, но единственное, что соответствует критериям, которые я думаю.
Ответ 7
следующее реализует предложение друга
#!/bin/bash
rcut(){
nu="$( echo $1 | cut -d"$DELIM" -f 2- )"
if [ "$nu" != "$1" ]
then
rcut "$nu"
else
echo "$nu"
fi
}
$ export DELIM=.
$ rcut a.b.c.d
d
Ответ 8
Если у вас есть файл с именем filelist.txt, который является списком путей, таких как: с:/dir1/dir2/file1.h C:/dir1/dir2/dir3/file2.h
то вы можете сделать это: rev filelist.txt | cut -d "/" -f1 | ред
Ответ 9
Если ваша входная строка не содержит прямой косой черты, вы можете использовать basename
и подоболочку:
$ basename "$(echo 'maps.google.com' | tr '.' '/')"
Он не использует sed
или awk
но также не использует cut
, так что я не совсем уверен, может ли это быть ответом на вопрос как его формулировка.
Это не очень хорошо работает, если обрабатывать входные строки, которые могут содержать косую черту. Обходной путь для такой ситуации - заменить косую черту другим символом, который, как вы знаете, не является частью допустимой входной строки. Например, символ pipe (|
) также не разрешен в именах файлов, поэтому это будет работать:
$ basename "$(echo 'maps.google.com/some/url/things' | tr '/' '|' | tr '.' '/')" | tr '|' '/'
Ответ 10
Добавление подхода к этому старому вопросу просто для удовольствия:
$ cat input.file # file containing input that needs to be processed
a;b;c;d;e
1;2;3;4;5
no delimiter here
124;adsf;15454
foo;bar;is;null;info
$ cat tmp.sh # showing off the script to do the job
#!/bin/bash
delim=';'
while read -r line; do
while [[ "$line" =~ "$delim" ]]; do
line=$(cut -d"$delim" -f 2- <<<"$line")
done
echo "$line"
done < input.file
$ ./tmp.sh # output of above script/processed input file
e
5
no delimiter here
15454
info
Только резать и колотить. Ну и эхо, наверное.
Ответ 11
Добавление подхода к этому старому вопросу просто для удовольствия:
$ cat input.file # file containing input that needs to be processed
a;b;c;d;e
1;2;3;4;5
no delimiter here
124;adsf;15454
foo;bar;is;null;info
$ cat tmp.sh # showing off the script to do the job
#!/bin/bash
delim=';'
while read -r line; do
while [[ "$line" =~ "$delim" ]]; do
line=$(cut -d"$delim" -f 2- <<<"$line")
done
echo "$line"
done < input.file
$ ./tmp.sh # output of above script/processed input file
e
5
no delimiter here
15454
info
Помимо bash, используется только разрез. Ну и эхо, наверное.
Ответ 12
Я понял, что если мы просто убедимся, что конечный разделитель существует, он работает. Так что в моем случае у меня есть запятые и пробелы. Я добавляю пробел в конце;
$ ans="a, b"
$ ans+=" "; echo ${ans} | tr ',' ' ' | tr -s ' ' | cut -d' ' -f2
b