Extrahieren Sie einen Teil einer Zeile bis zu einer bestimmten Zeichenfolge

Extrahieren Sie einen Teil einer Zeile bis zu einer bestimmten Zeichenfolge

Nehmen wir an, ich habe eine Datei mit Zeilen wie:

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

Gibt es eine Möglichkeit, einen Teil der Zeilen bis zu extrahieren bin? Ich meine, nehmen wir an, diese Zeilen sind file.txtdann

$ <some_command> file.txt 
/java/jdkxx/jvm_jdk/bin/
/java/jre/jre_jvm/bin/
/foo/bar/bin/

Antwort1

Es gibt viele Möglichkeiten, dies zu tun. Hier sind einige:

# 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

Antwort2

Eine reine Bash-Methode:

while read -n line
do
    [[ $line =~ /bin/ ]] && printf "%s\n" "${line/%\/bin\/*//bin/}"
done

Antwort3

Was, kein Perl?

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

Wenn Sie das wissenalleZeilen das gewünschte Muster enthalten, können Sie es wie folgt vereinfachen:

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

Dies \Kist ein PCRE-Ausdruck, der „alles vor dem \K“ bedeutet.


Sie können auch Dinge tun wie

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

Dadurch wird das Feldtrennzeichen ( FS) von awk auf gesetzt /binund dann das erste Feld und der Wert von FS(der ist /bin) gedruckt. Auch hier wird davon ausgegangen, dass Sie jede Zeile wollen. Wenn nicht, verwenden Sie stattdessen Folgendes:

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

Antwort4

Neben anderen guten Antworten können Sie auch Folgendes versuchen, um sicherzustellen, dass alles, was nach kommt /bin/, nicht gedruckt wird:

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

Beispiel:

$ 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/

Hier verwenden wir diePCREmit positivem Rückblick, (?<=/bin/)um sicherzustellen, dass wir nur bis zu dem Punkt gelangen /, an dem wir /bin/endlich angekommen sind.

verwandte Informationen