Часть извлечения строки до конкретной строки

Давайте предположим, что у меня есть файл со строками как:

/java/jdkxx/jvm_jdk/bin/opt
/java/jre/jre_jvm/bin/opt
/foo/bar/bin/other/stuff/here

Есть ли способ, до которого я могу извлечь часть строк bin. Я имею в виду, предполагаю, что те строки в file.txt затем

$ <some_command> file.txt 
/java/jdkxx/jvm_jdk/bin/
/java/jre/jre_jvm/bin/
/foo/bar/bin/
3
задан 10 March 2015 в 14:05

5 ответов

Существует много способов сделать это. Вот некоторые:

# greedily caputure up to the last slash
grep -o '.*/bin/' file.txt
# remove all non-slash chars from the end of each line
sed 's#\(/bin/\).*$#\1#' file.txt
# using slash as a delimiter, blank out the last field
awk -F/ -v OFS=/ '{for (i=1; i<=NF; i++) if ($i == "bin") {NF=i; break}} 1' file.txt
8
ответ дан 17 November 2019 в 09:08

Чистый удар путь:

while read -n line
do
    [[ $line =~ /bin/ ]] && printf "%s\n" "${line/%\/bin\/*//bin/}"
done
4
ответ дан 17 November 2019 в 09:08

В Python:

python3 -c "for l in open('f').readlines(): print(l[:l.find('/bin')+5])"

/java/jdkxx/jvm_jdk/bin/
/java/jre/jre_jvm/bin/

, где f является путем к файлу (в одинарных кавычках).

3
ответ дан 17 November 2019 в 09:08

Наряду с другими хорошими ответами, можно также попробовать следующее, которое удостоверится, что существует после /bin/, не будет распечатан:

grep -Po ".*/(?<=/bin/)" file

Пример:

$ cat test_file 
/java/jdkxx/jvm_jdk/bin/opt
/java/jre/jre_jvm/bin/opt/home

$ grep -Po ".*/(?<=/bin/)" test_file 
/java/jdkxx/jvm_jdk/bin/
/java/jre/jre_jvm/bin/

Здесь мы используем PCRE с положительным lookbehind (?<=/bin/), чтобы удостовериться, что мы берем только до эти /, где мы имеем /bin/ наконец.

2
ответ дан 17 November 2019 в 09:08

Что, никакой Perl?

perl -ne 's#/bin\K.*## && print' file

Если Вы знаете, что все строки содержат шаблон, который Вы хотите, можно упростить до:

perl -pe 's#/bin\K.*##' file

\K выражение PCRE, которое означает, "игнорируют все перед \K".


Можно также сделать вещи как

awk -F"/bin" '{print $1FS}' file

Это устанавливает разделитель полей awk (FS) к /bin, и затем печатает первое поле и значение FS (который является /bin). Тот, снова, предполагает желание каждой строки. В противном случае используйте этого вместо этого:

awk -F"/bin" '($2){print $1FS}' file
4
ответ дан 17 November 2019 в 09:08

Другие вопросы по тегам:

Похожие вопросы: