it-swarm.com.de

Wie kann ich die Dateinamenerweiterung in einem Shell-Skript entfernen?

Was ist los mit dem folgenden Code?

name='$filename | cut -f1 -d'.''

So wie es ist, bekomme ich die wörtliche Zeichenfolge $filename | cut -f1 -d'.', aber wenn ich die Anführungszeichen entferne, bekomme ich nichts. Inzwischen tippen

"test.exe" | cut -f1 -d'.'

in einer Shell gibt mir die gewünschte Ausgabe, test. Ich weiß bereits, dass $filename der richtige Wert zugewiesen wurde. Was ich tun möchte, ist einer Variablen den Dateinamen ohne die Erweiterung zuzuweisen.

97
mimicocotopus

Sie sollten die Befehlsersetzung Syntax $(command) verwenden, wenn Sie einen Befehl in script/command ausführen möchten.

So wäre deine Leitung 

name=$(echo "$filename" | cut -f 1 -d '.')

Code-Erklärung:

  1. echo ruft den Wert der Variablen $filename ab und sendet ihn an die Standardausgabe
  2. Dann packen wir die Ausgabe und leiten sie an den Befehl cut weiter
  3. Die cut verwendet die. als Trennzeichen (auch als Trennzeichen bezeichnet) zum Schneiden des Strings in Segmente und mit -f wählen wir aus, welches Segment wir in der Ausgabe haben möchten
  4. Die $()-Befehlsersetzung erhält dann die Ausgabe und gibt ihren Wert zurück
  5. Der zurückgegebene Wert wird der Variablen mit dem Namen name zugewiesen.

Beachten Sie, dass dies den Teil der Variablen bis zur ersten Periode angibt .:

$ filename=hello.world
$ echo "$filename" | cut -f 1 -d '.'
hello
$ filename=hello.hello.hello
$ echo "$filename" | cut -f 1 -d '.'
hello
$ filename=hello
$ echo "$filename" | cut -f 1 -d '.'
hello
72
Rohan

Sie können auch die Parametererweiterung verwenden:

$ filename=foo.txt
$ echo "${filename%.*}"
foo
170
chepner

Wenn Sie die Erweiterung kennen, können Sie basename verwenden.

$ basename /home/jsmith/base.wiki .wiki
base
86
Steven Penny

Wenn Ihr Dateiname einen anderen Punkt als den der Erweiterung enthält, verwenden Sie den folgenden Befehl:

echo $filename | rev | cut -f 2- -d '.' | rev
15
manish_s
file1=/tmp/main.one.two.sh
t=$(basename "$file1")                        # output is main.one.two.sh
name=$(echo "$file1" | sed -e 's/\.[^.]*$//') # output is /tmp/main.one.two
name=$(echo "$t" | sed -e 's/\.[^.]*$//')     # output is main.one.two

verwenden Sie, was Sie wollen. Hier gehe ich davon aus, dass der letzte . (Punkt) gefolgt von Text die Erweiterung ist.

13
Raghwendra

Wie Hawker65 in dem Kommentar von chepner antwortete, kümmert sich die meist gewählte Lösung weder um mehrere Erweiterungen (wie dateiname.tar.gz) noch um Punkte im Rest des Pfads (wie this.path/with) .dots/in.path.name) ..__ Eine mögliche Lösung ist:

a=this.path/with.dots/in.path.name/filename.tar.gz
echo $(dirname $a)/$(basename $a | cut -d. -f1)
1
MadMage
#!/bin/bash
filename=program.c
name=$(basename "$filename" .c)
echo "$name"

ausgänge:

program
0
booboo

Zwei Probleme mit Ihrem Code:

  1. Sie haben ein '(Häkchen) anstelle eines `(Zurück-Häkchen) verwendet, um die Befehle zu umgeben, die den String erzeugen, den Sie in der Variablen speichern möchten.
  2. Sie haben die Variable "$ dateiname" in der Pipe nicht mit dem Befehl "Ausschneiden" "nachgestellt".

Ich würde Ihren Code in "name =` echo $ filename | cut -f 1 -d "ändern. `", wie unten gezeigt (Beachten Sie wieder die hinteren Markierungen, die die Namensvariable definieren):

$> filename=foo.txt
$> echo $filename
foo.txt
$> name=`echo $filename | cut -f1 -d'.'`
$> echo $name
foo
$> 
0
FanDeLaU
#!/bin/bash
file=/tmp/foo.bar.gz
echo $file ${file%.*}

ausgänge:

/tmp/foo.bar.gz /tmp/foo.bar

Beachten Sie, dass nur die letzte Erweiterung entfernt wird.

0
C. Paul Bond

Meine Empfehlung ist die Verwendung des Basisnamens.
Es handelt sich in Ubuntu standardmäßig um visuell einfachen Code und behandelt die meisten Fälle. Hier sind einige Unterfälle, die sich mit Leerzeichen und Multidot/Untererweiterung befassen:

pathfile = "../ space fld/space -file.tar.gz"

echo $ {pathfile // + (/|. )}
In der Regel wird die Erweiterung zuerst entfernt. aber scheiterte in unserem Weg

echo "$ (basename" $ ​​{pathfile%. *} ")"
space -file.tar # Ich glaube, wir haben genau das gebraucht

Hier ist ein wichtiger Hinweis: Ich habe doppelte Anführungszeichen in doppelten Anführungszeichen verwendet, um mit Leerzeichen umzugehen. Das einfache Anführungszeichen wird nicht durch eine SMS mit dem Wert "$" ersetzt. Bash ist ungewöhnlich und liest aufgrund der Erweiterung "zweite" erste "Anführungszeichen".

Sie müssen jedoch noch an versteckte Dateien denken

hidden = "~/.bashrc" echo "$ (Basisname" $ ​​{hidden%.} ")" # erzeugt "~" !!!
nicht das erwartete "" Ergebnis. Verwenden Sie dazu $ HOME oder/home/user_path /
weil bash wieder "ungewöhnlich" ist und nicht "~" erweitert (nach bash BashPitfalls suchen)
hidden2 = "$ HOME/.bashrc"; echo '$ (Basisname "$ {pathfile%.
}")'

0
Alexey K.