
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.txt
dann
$ <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 \K
ist 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 /bin
und 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.